[英]Correct mro order attrs object can't find abstract property
以下運行良好:
from abc import ABC, abstractmethod
import attr
class A(ABC):
@abstractmethod
def prop(self):
pass
def foo(self):
print(self.prop())
class B:
def prop(self):
return 5
class C(B, A):
pass
C()
在這里, C
有一個從B
繼承的 function prop
,該道具在 MRO 訂單中首先找到,因此A
不會抱怨它的存在。 我也用dataclass
試過這個:
from abc import ABC, abstractmethod
from dataclasses import dataclass, field
class A(ABC):
@property
@abstractmethod
def prop(self):
pass
def foo(self):
print(self.prop())
@dataclass
class B:
prop: int = field(default=5)
class C(B, A):
pass
C()
但是,這不適用於attr
:
from abc import ABC, abstractmethod
import attr
@attr.s
class A(ABC):
@property
@abstractmethod
def prop(self):
pass
def foo(self):
print(self.prop())
@attr.s
class B:
prop: int = attr.ib(default=5)
@attr.s
class C(B, A):
pass
C()
運行它:
❯ python test.py
Traceback (most recent call last):
File "test_mro_abstract_property.py", line 22, in <module>
C()
TypeError: Can't instantiate abstract class C with abstract methods prop
我正在使用的代碼庫已經標准化了attr
的使用,所以如果可能的話,我想繼續使用attr
。 attrs
與dataclass
有什么不同,以至於它無法發現prop
成員? 這個問題有解決方法嗎?
我使用的 attr 版本是 22.1.0(最新版本)
有一種解決方法,但我不是 100% 為什么它有效:使 B 開槽:
@attr.s(slots=True)
class B:
prop: int = attr.ib(default=5)
讓它工作。
我懷疑這是因為 abc 檢查__slots__
並且它就在那里。
數據類將一些默認值作為 class 變量放在 class 主體上,但不是全部。
例如,這失敗了:
@dataclass
class B:
prop: list = field(default_factory=list)
這種不一致是我不喜歡以特殊方式處理某些默認值的原因。
JFTR,在現代 attrs(2020 年 8 月的 20.1.0)中,您的代碼將如下所示(並且可以工作,因為默認情況下插槽處於打開狀態):
from abc import ABC, abstractmethod
import attr
@attr.define
class A(ABC):
@property
@abstractmethod
def prop(self):
pass
def foo(self):
print(self.prop())
@attr.define
class B:
prop: int = attr.field(default=5)
@attr.define
class C(B, A):
pass
C()
(如果您同意要求 21.3,您甚至可以使用import attrs
)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.