[英]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.