5 ms·
Judging from your confrontational tone I will probably regret commenting but here goes. Arguments accepted in __init__() are not necessarily tied to the so-cal
by ambivalence 9y ago
Judging from your confrontational tone I will probably regret commenting but here goes.
Arguments accepted in __init__() are not necessarily tied to the so-called "shape of the type" at runtime. Fields with init=False, and the presence of ClassVar and InitVar is just two examples.
In terms of types of arguments passed to __init__(), they totally can be incompatible with the runtime type of the given field. There's nothing wrong with that. On the contrary, that is a useful feature. The obvious example is factories for field defaults. E.g. you can't store a list instance as a default value, it would be reused across your type's instances. Instead, you use default_factory=list. But when you do, what type does the respective argument to __init__ accept? Well, it's Union[YourType, MISSING] because you can omit it and it will initialize your type for you.
Type conversion is another common example. Your __init__ might accept timestamps as strings but always convert them to datetimes. Maybe you accept Unicode strings but internally store as bytes or vice versa? Maybe you support an external API so you have to accept a bunch of arguments that you later convert to a saner internal state? There are numerous use cases.
Summing up, don't confuse the signature of __init__ with the type shape.
- weberc2 9y agoI disagree. __init__() should do little more than assign attributes to parameter values, with the exception of handling `None` default parameters, and this exception only exists because Python's default parameters don't behave intuitively.
- kstrauser 9y agoThey're not intuitive, but they are consistent. It would be very surprising if `a=[]` behaved differently in a function definition (which isn't just syntax, but an executable Python statement) than elsewhere.
- weberc2 9y agoI disagree. ‘a=[]’ is inconsistent in function definitions today because the rhs is evaluated at interpreter load time but the assignment is evaluated at call time. The intuitive thing is would be to evaluate the whole expression at once (at call time) just like everywhere else.