如何在不覆盖父函数的情况下 return 超类的值?

How can I return a value to a superclass without overriding the parent function?

我想定义一个与其父函数同名的函数,returns 一个父函数可以接收和使用的值。虽然我认为可以通过元class实现这一点,但我不确定人们会怎么做(假设这是可能的)以及是否有更好、更清洁的解决方案。

我想要的格式如下所示。 Child class 将由我以外的开发人员定义,因此我希望限制尽可能少。 (例如,理想情况下,我不希望使用 super(Child).f(a) 来替换 return a。)我也不确定如何在我的模型中使用关键字参数,这会更可取。

class Parent:
    def f(self, arg):
        print("Received {}.".format(arg))
        return arg ** 3

class Child(Parent):
    def f(self, c, b, a):
        print(a, b, c)
        return a

# Prints "2 1 0" and "Received 2.". Sets value to 8.
value = Child().f(0, 1, 2)

此语句存在一个关键问题:

I would like to define a function with the same name as its parent which returns a value that the parent can receive

请问,为什么需要这个?

Child class 中的 f 与 Parent class 中的 f 完全不同,所以它们的命名相同即使你让它工作也非常令人困惑。

假设我用你的 Parent:

写了 child class
class Child(Parent):
    def f(self):
        return 2

我希望 Child().f() 到 return 2,但是如果你在添加 arg ** 3 的幕后添加隐藏逻辑,那么我将得到 8,并且完全困惑和诅咒您的图书馆添加了非常 non-intuitive 规则。


相反,为什么不使用一个函数并在 subclasses:

中定义额外的逻辑辅助函数
class Parent:
    def f(self, *v_args):
        arg = self.helper_f(*v_args)
        print("Received {}.".format(arg))
        return arg ** 3

    def helper_f(self,*args):
        "really should be an abstract method, must be implemented in a subclass"
        raise NotImplementedError("Must override in a subclass!") 

class Child(Parent):
    def helper_f(self, c, b, a):
        print(a, b, c)
        return a

# Prints "Received 2.". Sets value to 8.
value = Child().f(0, 1, 2)

当然,是的,从技术上讲,您 可以 使用元 class 自动执行此操作。但同样,对于使用您的 Parent class

的任何人,这将 完全混淆
class Child_Method_Redirector(type):
    def __new__(meta, name, bases, cls_dict):
        if bases is not ():
            if "f" in cls_dict:
                cls_dict["_auto_renamed_helper_f"] = cls_dict["f"]
                del cls_dict["f"]
        return type.__new__(meta,name,bases,cls_dict)


class Parent(metaclass=Child_Method_Redirector):
    def f(self, *v_args):
        arg = self._auto_renamed_helper_f(*v_args)
        print("Received {}.".format(arg))
        return arg ** 3

class Child(Parent):
    def f(self):
        return 2

# now it does Print "Received 2." and Sets value to 8.
value = Child().f()

但是请不要这样做,这违背了the zen

Explicit is better than implicit.
There should be one-- and preferably only one --obvious way to do it.
If the implementation is hard to explain, it's a bad idea.