我想创建一个抽象类,以便子类在实例化时如果不实现抽象属性则会引发错误。如果属性是方法而不是属性,也应该引发错误。我的尝试:
from abc import ABC, abstractmethod
class IClass(ABC):
@property
@abstractmethod
def attr(self):
pass
不幸的是,这无法阻止使用attr
方法而不是属性来实例化子类。
解决方案应该产生以下结果:
class C(IClass):
pass
C() # Must fail because 'attr' has not been implemented
class C(IClass):
def attr(self):
pass
C().attr # Must fail because attribute 'attr' is a method rather than a property
class C(IClass):
attr = 'attr'
C().attr # Must pass because 'attr' is a property
手册:docs。
答案 0 :(得分:0)
这不像装饰器那样方便,但您可以验证该属性是__new__
中的属性,如:
from abc import ABC, abstractmethod
class IClass(ABC):
def __new__(cls, *args, **kwargs):
new = super().__new__(cls, *args, **kwargs)
if not isinstance(type(new).attr, property):
raise TypeError('attr must be a property')
return new
@property
@abstractmethod
def attr(self):
pass
class A(IClass):
pass
try:
# Must fail because 'attr' has not been implemented
A()
except Exception as exc:
print('A Passed: {}'.format(exc))
class B(IClass):
def attr(self):
pass
try:
# Must fail because attribute 'attr' is a method rather than a property
B()
except Exception as exc:
print('B Passed: {}'.format(exc))
class C(IClass):
@property
def attr(self):
return 'Good'
# Must pass because 'attr' is a property
print('C Passed: {}'.format(C().attr))
A Passed: Can't instantiate abstract class A with abstract methods attr
B Passed: attr must be a property
C Passed: Good