class 中所有方法的抽象方法装饰器
abstractmethod decorator to all methods in class
我试图实现我不需要一直使用所有方法装饰器的地方@abstractmethod
首先,我实现了 class 装饰器,但这不需要任何结果:
from abc import ABC, abstractmethod
def interface(cls):
for attr in cls.__dict__:
if callable(getattr(cls, attr)):
setattr(cls, attr, abstractmethod(getattr(cls, attr)))
return cls
@interface
class A(ABC):
def foo(self):
pass
def bar(self):
pass
class B(A):
def foo(self):
pass
b = B()
其次,我尝试在 class 中使用 __init__
方法实现它,但它也没有给出任何结果:
class Interface(ABC):
def __init__(self):
for attr in self.__dict__:
attr_obj = getattr(self, attr)
if callable(attr_obj):
setattr(self, attr, abstractmethod(attr_obj))
class A(Interface):
def __init__(self):
super().__init__()
def foo(self):
pass
def bar(self):
pass
class B(A):
def foo(self):
pass
b = B()
如何实现 class 中的所有方法都用 @abstractmethod
修饰的方法?
就像@juanpa.arrivillaga提到的那样,在实例化class之后装饰抽象class已经太晚了,因为ABC
改变了它的class成员它的元class, ABCMeta
.
相反,您可以 subclass ABCMeta
(如下例中的 Interface
)并对 class 的 classdict
参数进行修改constructor before调用superclass.
的构造函数
由于child classes应该默认实现抽象方法,典型情况下不会继续声明方法abstract,所以应该避免用[=19=装饰child classes的方法],但由于子 classes 将继承父的元 class,因此您必须显式地使 Interface
return 的构造函数成为 [=15] 的对象=] 而不是 Interface
本身,这样自定义行为就不会被继承:
from abc import ABCMeta, abstractmethod
class Interface(ABCMeta):
def __new__(metacls, name, bases, classdict):
for attr, value in classdict.items():
if callable(value):
classdict[attr] = abstractmethod(value)
return super().__new__(ABCMeta, name, bases, classdict)
这样:
class A(metaclass=Interface):
def foo(self):
pass
def bar(self):
pass
class B(A):
def foo(self):
pass
b = B()
会产生:
TypeError: Can't instantiate abstract class B with abstract method bar
同时:
class A(metaclass=Interface):
def foo(self):
pass
def bar(self):
pass
class B(A):
def foo(self):
pass
def bar(self):
pass
会运行没有错误。
我试图实现我不需要一直使用所有方法装饰器的地方@abstractmethod
首先,我实现了 class 装饰器,但这不需要任何结果:
from abc import ABC, abstractmethod
def interface(cls):
for attr in cls.__dict__:
if callable(getattr(cls, attr)):
setattr(cls, attr, abstractmethod(getattr(cls, attr)))
return cls
@interface
class A(ABC):
def foo(self):
pass
def bar(self):
pass
class B(A):
def foo(self):
pass
b = B()
其次,我尝试在 class 中使用 __init__
方法实现它,但它也没有给出任何结果:
class Interface(ABC):
def __init__(self):
for attr in self.__dict__:
attr_obj = getattr(self, attr)
if callable(attr_obj):
setattr(self, attr, abstractmethod(attr_obj))
class A(Interface):
def __init__(self):
super().__init__()
def foo(self):
pass
def bar(self):
pass
class B(A):
def foo(self):
pass
b = B()
如何实现 class 中的所有方法都用 @abstractmethod
修饰的方法?
就像@juanpa.arrivillaga提到的那样,在实例化class之后装饰抽象class已经太晚了,因为ABC
改变了它的class成员它的元class, ABCMeta
.
相反,您可以 subclass ABCMeta
(如下例中的 Interface
)并对 class 的 classdict
参数进行修改constructor before调用superclass.
由于child classes应该默认实现抽象方法,典型情况下不会继续声明方法abstract,所以应该避免用[=19=装饰child classes的方法],但由于子 classes 将继承父的元 class,因此您必须显式地使 Interface
return 的构造函数成为 [=15] 的对象=] 而不是 Interface
本身,这样自定义行为就不会被继承:
from abc import ABCMeta, abstractmethod
class Interface(ABCMeta):
def __new__(metacls, name, bases, classdict):
for attr, value in classdict.items():
if callable(value):
classdict[attr] = abstractmethod(value)
return super().__new__(ABCMeta, name, bases, classdict)
这样:
class A(metaclass=Interface):
def foo(self):
pass
def bar(self):
pass
class B(A):
def foo(self):
pass
b = B()
会产生:
TypeError: Can't instantiate abstract class B with abstract method bar
同时:
class A(metaclass=Interface):
def foo(self):
pass
def bar(self):
pass
class B(A):
def foo(self):
pass
def bar(self):
pass
会运行没有错误。