4

所以我喜欢使用 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'
4

2 回答 2

6

如果您通过@attr.s(auto_attribs=True, init=False),则 attrs 不会创建__init__方法(对于repr, eq, ... 的工作方式相同)。


从 attrs 20.1.0 开始,如果您传递@attr.s(auto_attribs=True, auto_detect=True)或使用 NG API @attr.define(不需要 args),它将自动检测当前类上是否存在自定义__init__(以及所有其他__方法)并且不会覆盖它。

于 2019-10-05T20:06:31.110 回答
4

attrs by Examples ”页面说:

有时,您希望您的类的 __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)
于 2019-10-03T15:45:41.643 回答