You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/index.md
+76-27Lines changed: 76 additions & 27 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,24 +6,26 @@
6
6
7
7
[](https://smarie.github.io/python-autoclass/)[](https://pypi.python.org/pypi/autoclass/)[](https://pepy.tech/project/autoclass)[](https://pepy.tech/project/autoclass)[](https://github.com/smarie/python-autoclass/stargazers)
8
8
9
-
!!! warning "`include` and `exclude` have been fixed in `@autodict` and `@autohash`, you do not need to add an underscore anymore when the attribute corresponds to a property. See [#21](https://github.com/smarie/python-autoclass/issues/21)"
9
+
!!! success "`autoclass` is now fully compliant with [`pyfields`](https://smarie.github.io/python-pyfields/) ! Check out how you can create very compact classes [here](#pyfields-combo)"
10
10
11
-
`autoclass` provides tools to automatically generate python classes code. The objective of this library is to reduce the amount of redundancy by automatically generating parts of the code from the information already available somewhere else (typically, in the constructor signature). It is made of several independent features that can be combined:
11
+
`autoclass` provides tools to automatically generate python classes code. The objective of this library is to reduce the amount of redundancy by automatically generating parts of the code from the information already available somewhere else (in the constructor signature or in the `pyfields` fields for example). It is made of several independent features that can be combined:
12
12
13
13
* with `@autoargs` you don't have to write `self.xxx = xxx` in your constructor
14
-
* with `@autoprops` all your fields become `properties` and their setter is annotated with the same PEP484 type hints and value validation methods than the corresponding constructor argument
15
-
* with `@autohash`, your object is hashable based on the tuple of all fields
14
+
* with `@autoprops` all or part your constructor arguments become `properties` and their setter is annotated with the same PEP484 type hints and value validation methods
15
+
* with `@autohash`, your object is hashable based on the tuple of all fields (so it can be used as a dictionary key or put in a set)
16
16
* with `@autodict`, your object behaves like a dictionary, is comparable with dictionaries, and gets a string representation
17
-
* with `@autoclass`, you get all of the above at once
17
+
* with `@autorepr`, your object gets a string representation (use either this or `@autodict`, not both at the same time)
18
+
* with `@autoclass`, you get all of the above at once (but you can still disable some of them)
18
19
19
-
The intent is similar to [attrs](https://github.com/python-attrs/attrs) and [PEP557](https://www.python.org/dev/peps/pep-0557): remove boilerplate code. However as opposed to these,
20
+
The intent is similar to [attrs](https://github.com/python-attrs/attrs) and [PEP557 dataclasses](https://www.python.org/dev/peps/pep-0557): remove boilerplate code. However as opposed to these,
20
21
21
-
* this library does not change anything in your coding habits: you still create a `__init__` constructor, and everything else is provided with decorators.
22
-
* all decorators can be used independently, for example if you just need to add a dictionary behaviour to an existing class you can use `@autodict` only. Besides, all decorators can be manually applied to already existing classes.
23
-
* all created code is not dynamically compiled using `compile`. This obviously leads to poorer performance than `attrs` in highly demanding applications, but for many standard use cases it works well, and provides better debug-ability (you can easily step through the generated functions to understand what's going on)
24
-
* as opposed to `attrs`, setters are generated for the fields so validation libraries such as [valid8](https://smarie.github.io/python-valid8/) can wrap them.
22
+
* this library can be applied on *any* class. It does not change anything in your coding habits: you can still create a `__init__` constructor, and everything else is provided with decorators.
23
+
* if information about fields is available from another library, `autoclass` can easily leverage it : for example you can now use [`pyfields`](https://smarie.github.io/python-pyfields/) to declare the fields, `autoclass` will support it.
24
+
* all decorators above can be used independently, for example if you just need to add a dictionary behaviour to an existing class you can use `@autodict` only.
25
+
* all created code is simple and readable. You can easily step through the generated functions in debug mode to understand what's going on
26
+
* as opposed to `attrs`, setters are generated for the fields so validation libraries such as [valid8](https://smarie.github.io/python-valid8/) can wrap them. Alternatively if you use `pyfields`, it directly provides this feature.
25
27
26
-
Finally, `autoclass` simply generates the same code that you *would have written* manually. For this reason, in many cases you can use *other* libraries on top of the resulting classes without hassle. A good example is that you can use any PEP484 type checking library of your choice.
28
+
In other words, `autoclass` simply generates the same code that you *would have written* manually. For this reason, in many cases you can use *other* libraries on top of the resulting classes without hassle. A good example is that you can use any PEP484 type checking library of your choice.
27
29
28
30
29
31
## Installing
@@ -34,21 +36,21 @@ Finally, `autoclass` simply generates the same code that you *would have written
34
36
35
37
You may wish to also install
36
38
37
-
* a PEP484-based type checker: [enforce](https://github.com/RussBaz/enforce) or [pytypes](https://github.com/Stewori/pytypes).
38
-
* a value validator: [valid8](https://smarie.github.io/python-valid8/) was originally created in this project and is now independent. It provides the `@validate` annotation (and it also provides the `Boolean` type)
39
-
* Alternatively, you may use[PyContracts](https://andreacensi.github.io/contracts/index.html) to perform type and value validation at the same time using `@contract`, but this will not benefit from PEP484 and uses a dedicated syntax. This documentation also shows some examples.
39
+
*[`pyfields`](https://smarie.github.io/python-pyfields/) to create compact classes.
40
+
* a PEP484-based type checker: [typeguard](https://github.com/agronholm/typeguard) , [pytypes](https://github.com/Stewori/pytypes) or [enforce](https://github.com/RussBaz/enforce).
41
+
* a value validator: [valid8](https://smarie.github.io/python-valid8/) was originally created in this project and is now independent.
42
+
43
+
Alternatively, you may use [PyContracts](https://andreacensi.github.io/contracts/index.html) to perform type and value validation at the same time using `@contract`, but this will not benefit from PEP484 and uses a dedicated syntax. This documentation also shows some examples.
40
44
41
45
42
46
```bash
43
-
> pip install enforce
47
+
> pip install pyfields
44
48
> pip install pytypes
45
49
> pip install valid8
46
50
> pip install PyContracts
47
51
```
48
52
49
-
## Usage examples
50
-
51
-
### Basic
53
+
## 1. Basic usage
52
54
53
55
The following code shows how you define a `House` with two attributes `name` and `nb_floors`:
If you already use [`pyfields`](https://smarie.github.io/python-pyfields/) to define mandatory/optional fields with type/value validation, simply decorate your class with `@autoclass` and you'll get all of the above (dict view, hashability, string representation, equality...) too:
112
+
113
+
```python
114
+
from pyfields import field
115
+
from autoclass import autoclass
116
+
from mini_lambda import x
117
+
118
+
@autoclass
119
+
class House:
120
+
name: str = field(check_type=True, doc="the name of your house")
121
+
nb_floors: int = field(default=1, check_type=True, doc="the nb floors",
122
+
validators={
123
+
"should be positive": x >= 0,
124
+
"should be a multiple of 100": x % 100 == 0
125
+
})
126
+
127
+
```
128
+
129
+
Indeed behind the scenes, if `autoclass` detects that your class uses `pyfields`, it will automatically use the fields rather than the constructor signature to get the list of fields. You can check that all the features are there:
130
+
131
+
```bash
132
+
>>> obj = House('my_house', 200)
133
+
134
+
>>> print(obj) # string representation
135
+
House(name='my_house', nb_floors=200)
136
+
137
+
>>> [att for att in obj.keys()] # dictionary behaviour
138
+
['name', 'nb_floors']
139
+
140
+
>>> assert {obj, obj} == {obj} # hashable: can be used in a set or as a dict key
Note: this works with python 2.7, and 3.5+. See [`pyfields` documentation ](https://smarie.github.io/python-pyfields/) for details.
147
+
148
+
## 2. Type and Value validation
107
149
108
-
### Type validation with PEP484
150
+
If you do not use `pyfields`, then you might be interested to add type and value validation to your fields through another means.
151
+
152
+
### a- PEP484 Type validation
109
153
110
154
#### enforce
111
155
@@ -154,8 +198,12 @@ class House:
154
198
pass
155
199
```
156
200
201
+
#### `typeguard`
202
+
203
+
TODO
157
204
158
-
### Simple Type+Value validation
205
+
206
+
### b- Simple Type+Value validation
159
207
160
208
#### valid8
161
209
@@ -229,9 +277,7 @@ class House:
229
277
```
230
278
231
279
232
-
### PEP484 Type+Value validation
233
-
234
-
#### enforce + valid8
280
+
### c- PEP484 Type+Value validation
235
281
236
282
Finally, in real-world applications you might wish to combine both PEP484 type checking and value validation. This works as expected, for example with `enforce` and `valid8`:
237
283
@@ -368,12 +414,15 @@ Really, *"there must be a better way"* : yes there is, and that's what this libr
368
414
369
415
* **`@autohash`** is a decorator for a whole class. It makes the class hashable by implementing `__hash__` if not already present, where the hash is computed from the tuple of selected fields (all by default, customizable).
370
416
417
+
* **`@autorepr`** is a decorator for a whole class. It adds a string representation by implementing `__str__` and `__repr__` if not already present.
418
+
371
419
* Equivalent manual wrapper methods are provided for all decorators in this library:
@@ -394,7 +443,7 @@ Really, *"there must be a better way"* : yes there is, and that's what this libr
394
443
395
444
* The new PEP out there, largely inspired by `attrs`: [PEP557](https://www.python.org/dev/peps/pep-0557). Check it out! There is also a [discussion on python-ideas](https://groups.google.com/forum/#!topic/python-ideas/8vUm84CCb3c).
396
445
397
-
* [decorator](http://decorator.readthedocs.io) library, which provides everything one needs to create complex decorators easily (signature and annotations-preserving decorators, decorators with class factory) as well as provides some useful decorators (`@contextmanager`, `@blocking`, `@dispatch_on`). We use it to preserve the signature of class constructors and overriden setter methods.
446
+
* [decorator](http://decorator.readthedocs.io) library, which provides everything one needs to create complex decorators easily (signature and annotations-preserving decorators, decorators with class factory) as well as provides some useful decorators (`@contextmanager`, `@blocking`, `@dispatch_on`). We used it to preserve the signature of class constructors and overriden setter methods. Now we use [`makefun`](https://smarie.github.io/python-makefun/) instead, which was inspired by it.
398
447
399
448
* When came the time to find a name for this library I was stuck for a while. In my quest for finding an explicit name that was not already used, I found many interesting libraries on [PyPI](http://pypi.python.org/). I did not test them all but found them 'good to know':
0 commit comments