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
This example also shows of some syntactic sugar for using the {obj}`attrs.validators.and_` validator: if you pass a list, all validators have to pass.
216
+
This example demonstrates a convenience shortcut:
217
+
Passing a list of validators directly is equivalent to passing them wrapped in the {obj}`attrs.validators.and_` validator and all validators must pass.
217
218
218
219
*attrs* won't intercept your changes to those attributes but you can always call {func}`attrs.validate` on any instance to verify that it's still valid:
219
-
When using {func}`attrs.define` or [`attrs.frozen`](attrs.frozen), *attrs* will run the validators even when setting the attribute.
220
+
221
+
When using {func}`attrs.define` or [`attrs.frozen`](attrs.frozen), however, *attrs* will run the validators even when setting the attribute.
220
222
221
223
```{doctest}
222
224
>>> i = C(4, 5)
@@ -241,7 +243,7 @@ TypeError: ("'x' must be <type 'int'> (got '42' that is a <type 'str'>).", Attri
241
243
```
242
244
243
245
Of course you can mix and match the two approaches at your convenience.
244
-
If you define validators both ways for an attribute, they are both ran:
246
+
If you use both ways to define validators for an attribute, they are both ran:
TypeError: ("'x' must be <class 'int'> (got '128' that is a <class 'str'>).", Attribute(name='x', default=NOTHING, validator=[<instance_of validator for type <class 'int'>>, <function fits_byte at 0x10fd7a0d0>], repr=True, cmp=True, hash=True, init=True, metadata=mappingproxy({}), type=None, converter=None), <class 'int'>, '128')
277
279
```
278
280
279
-
You can achieve the same by using the context manager:
281
+
... or within a context manager:
280
282
281
283
```{doctest}
282
284
>>> with attrs.validators.disabled():
@@ -292,8 +294,7 @@ TypeError: ("'x' must be <class 'int'> (got '128' that is a <class 'str'>).", At
292
294
293
295
## Converters
294
296
295
-
Finally, sometimes you may want to normalize the values coming in.
296
-
For that *attrs* comes with converters.
297
+
Sometimes, it is necessary to normalize the values coming in, therefore *attrs* comes with converters.
297
298
298
299
Attributes can have a `converter` function specified, which will be called with the attribute's passed-in value to get a new value to use.
299
300
This can be useful for doing type-conversions on values that you don't want to force your callers to do.
@@ -350,10 +351,10 @@ A converter will override an explicit type annotation or `type` argument.
350
351
351
352
## Hooking Yourself Into Initialization
352
353
353
-
Generally speaking, the moment you think that you need finer control over how your class is instantiated than what *attrs* offers, it's usually best to use a {obj}`classmethod` factory or to apply the [builder pattern](https://en.wikipedia.org/wiki/Builder_pattern).
354
+
Generally speaking, the moment you realize the need of finer control – than what *attrs* offers – over how a class is instantiated, it's usually best to use a {obj}`classmethod` factory or to apply the [builder pattern](https://en.wikipedia.org/wiki/Builder_pattern).
354
355
355
356
However, sometimes you need to do that one quick thing before or after your class is initialized.
356
-
And for that *attrs* offers three means:
357
+
For that purpose, *attrs* offers the following options:
357
358
358
359
-`__attrs_pre_init__` is automatically detected and run *before**attrs* starts initializing.
359
360
This is useful if you need to inject a call to `super().__init__()`.
Copy file name to clipboardExpand all lines: docs/why.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -269,7 +269,7 @@ is roughly
269
269
ArtisanalClass(a=1, b=2)
270
270
```
271
271
272
-
which is quite a mouthful and it doesn't even use any of *attrs*'s more advanced features like validators or defaults values.
272
+
which is quite a mouthful and it doesn't even use any of *attrs*'s more advanced features like validators or default values.
273
273
Also: no tests whatsoever.
274
274
And who will guarantee you, that you don't accidentally flip the `<` in your tenth implementation of `__gt__`?
275
275
@@ -293,5 +293,5 @@ If you don't care and like typing, we're not gonna stop you.
293
293
294
294
However it takes a lot of bias and determined rationalization to claim that *attrs* raises the mental burden on a project given how difficult it is to find the important bits in a hand-written class and how annoying it is to ensure you've copy-pasted your code correctly over all your classes.
295
295
296
-
In any case, if you ever get sick of the repetitiveness and drowning important code in a sea of boilerplate, *attrs* will be waiting for you.
296
+
In any case, if you ever get sick of the repetitiveness and the drowning of important code in a sea of boilerplate, *attrs* will be waiting for you.
0 commit comments