需求: 想给抽象方法类实现函数式调用,该怎么写
分开写,我知道怎么写,但是怎么让一个类同时具有两种特性?
抽象方法类
class A(ABC):
def __init__(self, name):
self.name = name
@abstractmethod
def run(self):
pass
class B(A):
def __init__(self, name):
super().__init__(name)
def run(self):
print(self.name)
实现函数式调用
class MetaB(type):
def __call__(cls, *args, **kwargs):
obj = super().__call__(*args, **kwargs)
return obj.run()
class B(metaclass=MetaB):
def run(self):
pass
怎么让 B 同时拥有两种特性?按我的理解要想让一个类实现函数式调用,就得在它的元类里面重载__call__
方法,可是抽象方法类实现的过程中已经定义了元类是 ABCMeta ,这种情况该怎么覆写呢?
解决了
from abc import ABC, abstractmethod, ABCMeta
class MetaB(ABCMeta):
def __call__(cls, *args, **kwargs):
obj = super().__call__(*args, **kwargs)
return obj.run()
class A(ABC):
def __init__(self, name):
self.name = name
@abstractmethod
def run(self):
pass
class B(A, metaclass=MetaB):
def __init__(self, name):
super().__init__(name)
def run(self):
print(self.name)
if __name__ == '__main__':
B(123)
错误提示没好好读。。。 TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass #of the metaclasses of all its bases
1
BingoXuan 2022-05-17 12:15:35 +08:00
|
3
fgwmlhdkkkw 2022-05-17 12:27:34 +08:00
__new__
|
4
caneman OP @BingoXuan
大概这么一个场景,很多类,每个类有细微不同,把里面共同的部分提取出来,放在一个抽象类里面,也定义了一些子类必须实现的方法(代码 1 的部分) 所有这些子类,并不需要保持一个对象,可以看作一个大号的函数,我想实现,所有的子类,能通过 B() 这样就直接执行(代码 2 的部分) 有没有一种方法,能让 B 同时实现两种功能,即在 1 的基础上,让其子类能实现,子类()这样作为一个函数直接执行的功能 |
5
BingoXuan 2022-05-17 12:31:30 +08:00
|
6
caneman OP @BingoXuan 比__new__的时机要晚,在 cls.__init__之后(下面的代码不对,但是大概这么个意思)
|
7
caneman OP class A(ABC):
def __call__(self, *args, **kwargs): obj = super().__call__(*args, **kwargs) return obj.run() def __init__(self, name): self.name = name @abstractmethod def run(self): pass class B(A): def __init__(self, name): super().__init__(name) def run(self): print(self.name) |