使 __call__ 成为可用于所有派生类的基类中的特定接口

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


class Base:

    def fn(self, *input):

        # ...


    __call__ = fn


class Derived(Base):

    def fn(self, input):

        # ...


    __call__ = fn

我知道有一种设计只__call__在 Base 类和 in__call__的函数体中定义 a ,以将其工作转换为fn每个派生类实现自己的fn. 语义就像“继承一个公共接口并从Base实现,并且在这个公共接口中,每个Derived类定义了自己的实现版本”。


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


那么无论如何要__call__在 Base 类中指定唯一的一次,但使其可用于所有派生类?


慕盖茨4494581
浏览 194回答 2
2回答

牛魔王的故事

如果您使用的是 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.fnclass Derived(Base):    def fn(self, arg):        print("In derived")        return argBase()(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.fnclass Base(metaclass=BaseMeta):    def fn(self, *args):        return argsclass Derived(Base):    def fn(self, arg):        print("In derived")        return arg

九州编程

在您提供的示例中,无需使用__call__. 已经有一个非常好的机制,因为python会调用类构造函数。如此简单,def __init__(self, *args):并根据需要调用该代码fn。您提到了不同的参数列表,但没有描述如何区分它们。如果它是一个简单的标准,例如len(args),那么您所拥有的就足够了。如果它更复杂,您可能想要放入**kwargs签名,并让每个方法只挑选它识别的关键字参数。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python