[英]abstractmethod decorator to all methods in class
我试图让我意识到我不需要一直使用所有方法装饰器@abstractmethod
首先,我实现了类装饰器,但这不需要任何结果:
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()
其次,我尝试在类中的__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()
我怎样才能实现类中所有方法都用@abstractmethod
装饰的方法?
就像@juanpa.arrivillaga 提到的那样,在类被实例化后装饰抽象类为时已晚,因为ABC
用它的元类ABCMeta
改变了它的类成员。
相反,您可以子类化ABCMeta
(作为下面示例中的Interface
)并在调用超类的构造函数之前修改类构造函数的classdict
参数。
由于子类应该默认实现抽象方法,并且在典型情况下不会继续声明抽象方法,因此您应该避免使用abstractmethod
装饰子类的方法,但是由于子类会继承父类的元类,因此您必须明确地使Interface
的构造函数返回ABCMeta
的对象而不是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
会运行没有错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.