如何在不重写父函数的情况下将值返回给超类?

2024-04-19 10:13:04 发布

您现在位置:Python中文网/ 问答频道 /正文

我想定义一个与父函数同名的函数,它返回父函数可以接收和使用的值。尽管我认为用元类实现这一点是可能的,但我不确定如何做到这一点(假设这是可能的),以及是否有更好、更干净的解决方案。你知道吗

我想要的格式如下所示。Child类将由我以外的开发人员定义,因此我希望限制尽可能少。(例如,在理想情况下,我不想用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)

Tags: 函数selfchildreturn定义valuedef格式
1条回答
网友
1楼 · 发布于 2024-04-19 10:13:04

这种说法有一个关键问题:

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

请问,这有什么必要?你知道吗

子类中的f与父类中的f完全不同,因此将它们命名为同一事物是非常令人困惑的,即使您确实让它工作了。你知道吗

假设我使用Parent编写了子类:

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

我希望Child().f()返回2,但是如果您在添加arg ** 3的幕后添加隐藏逻辑,那么我将得到8,并且完全困惑并诅咒您的库添加了非常不直观的规则。你知道吗


相反,为什么不使用一个函数并在子类中定义额外的逻辑助手函数:

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)

当然,是的,从技术上讲,可以通过meta-class实现自动化。但是,对于任何使用Parent类的人来说,这都是完全混淆的

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.

相关问题 更多 >