【发布时间】:2021-09-17 13:53:43
【问题描述】:
我试图让我意识到我不需要一直使用所有方法装饰器@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 装饰的方式?
【问题讨论】:
-
我相信 ABC 的实现依赖于元类魔法,需要在元类实例化之前修饰方法(即在类主体中......)。当您的装饰器拥有实例化的类对象时,为时已晚。您可以尝试使用适当修饰的方法创建类的副本,然后再将它们与类命名空间一起传递给元类构造函数。不过似乎很冒险。我只会咬紧牙关。
-
您的第二种方法不起作用,
self.__dict__是 实例命名空间,它不包含方法。再说一次,现在ABCMeta做任何事情都为时已晚 -
为什么不使用
mypy的静态类型检查和Protocol的结构子类型? -
@juanpa.arrivillaga 您可以通过覆盖元类的
__new__方法并在调用原始元类的__new__方法之前更改类成员来规避元类的魔法。 -
我已经用更好的方法更新了我的答案,以避免使用
abstractmethod装饰子类的方法。
标签: python python-3.x python-decorators abc