gpt4 book ai didi

python - 使 __call__ 成为基类中可用于所有派生类的特定接口(interface)

转载 作者:行者123 更新时间:2023-12-01 08:35:49 26 4
gpt4 key购买 nike

我有一个基类,其中有一个公共(public)fn。我想让层次系统中的所有类都可调用,并且它们的 __call__ 实际上将它们的工作翻译为 fn,语义类似于 Class.__call__ = fn。以下代码显示了我目前的实现方式。

class Base:
def fn(self, *input):
# ...

__call__ = fn

class Derived(Base):
def fn(self, input):
# ...

__call__ = fn

我知道有一种设计,只在基类中定义一个__call__,并在__call__的函数体中,将其工作翻译为fn,每个派生类都实现自己的fn。语义就像“从 Base 继承一个公共(public)接口(interface)并实现,在这个公共(public)接口(interface)中,每个派生类定义自己的实现版本”。

但是,某些 fn 具有不同的参数列表,并不总是与 Base 相同,就像我上面展示的情况一样。上面的代码可以工作,但我想一定有更好的解决方案,无需在层次结构系统的所有类中重复定义。

那么有没有办法在基类中仅指定一次__call__,但使其可用于所有派生类?

最佳答案

如果您使用的 Python 版本 >= 3.6,您可以编写 __init_subclass__ Base 类的方法,将子类的 __call__ 属性分配为等于其 fn 属性:

class Base:
def fn(self, *args):
return args
__call__ = fn
def __init_subclass__(cls):
cls.__call__ = cls.fn

class Derived(Base):
def fn(self, arg):
print("In derived")
return arg


Base()(1, 2, 3)
# (1, 2, 3)

Derived()(1)
# In derived
# 1

如果您使用旧版本的 Python,则可以使用元类实现类似的效果。

class BaseMeta(type):
def __init__(cls, *args, **kwargs):
super().__init__(*args, **kwargs)
cls.__call__ = cls.fn

class Base(metaclass=BaseMeta):
def fn(self, *args):
return args

class Derived(Base):
def fn(self, arg):
print("In derived")
return arg

关于python - 使 __call__ 成为基类中可用于所有派生类的特定接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53735342/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com