तो मैं attr का उपयोग करना पसंद करता हूं लेकिन कभी-कभी मुझे अपना काम खुद करना पड़ता है। क्या मैं __init__ विधि को अपने साथ ओवरराइड कर सकता हूं?

import attr
@attr.s(auto_attribs=True)
class MyClass:
     i: int
     def __init__(self, i, special=None):
          if special:
               self.i = special
          else:
               self.i = i
>>> a = MyClass(i=1,special=2)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
    a = MyClass(i=1,special=2)
TypeError: __init__() got an unexpected keyword argument 'special'

एक और उदाहरण:

@attr.s(auto_attribs=True)
class MyOtherClass:
     i: int
     def __init__(self, i, **kwargs):
         self.i = kwargs.get('magic',i)



>>> a = MyOtherClass(i=5,magic=12)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
    a = MyOtherClass(i=5,magic=12)
TypeError: __init__() got an unexpected keyword argument 'magic'
3
polo 3 अक्टूबर 2019, 18:33

2 जवाब

सबसे बढ़िया उत्तर

यदि आप @attr.s(auto_attribs=True, init=False) पास कर लेते हैं, तो attrs एक __init__ विधि नहीं बनाएगा (repr, eq, ... के लिए समान रूप से कार्य करता है)।

कस्टम विधि की उपस्थिति का स्वचालित रूप से पता लगाना और आपके लिए init=False सेट करना तत्काल रोडमैप पर है। मुझे उम्मीद है कि यह अगली रिलीज के साथ शिप होगा।

1
hynek 5 अक्टूबर 2019, 23:06

"attrs byexamples" पेज कहता है:

कभी-कभी, आप चाहते हैं कि आपकी कक्षा की __init__ विधि केवल इनिशियलाइज़ेशन, सत्यापन, आदि से अधिक हो, जो @attr.s का उपयोग करते समय आपके लिए स्वचालित रूप से हो जाती है। ऐसा करने के लिए, बस अपनी कक्षा में एक __attrs_post_init__ विधि परिभाषित करें। इसे उत्पन्न __init__ विधि के अंत में बुलाया जाएगा।

>>> @attr.s
... class C(object):
...     x = attr.ib()
...     y = attr.ib()
...     z = attr.ib(init=False)
...
...     def __attrs_post_init__(self):
...         self.z = self.x + self.y
>>> obj = C(x=1, y=2)
>>> obj
C(x=1, y=2, z=3)
1
ababak 3 अक्टूबर 2019, 18:45