Search code examples
pythonpython-3.7python-attrs

in a python attrs class, how can I override generated __init__ with my own


So I like to use attr but sometimes I need to do my own thing. can I override the __init__ method with my own?

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'

Another example:

@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'

Solution

  • If you pass @attr.s(auto_attribs=True, init=False), a attrs won't create an __init__ method (works the same for repr, eq, ...).


    As of attrs 20.1.0, if you pass @attr.s(auto_attribs=True, auto_detect=True) or use the NG API @attr.define (no args necessary), it will automatically detect the presence of a custom __init__ (and every other __ method) on the current class and won’t overwrite it.