【问题标题】:How would a parent class call its own method within itself in Python父类如何在 Python 中调用自己的方法
【发布时间】:2016-09-17 18:26:06
【问题描述】:

我正在尝试使用 Mixins、MyCollectionVal5Val10 创建具体类 Val15Val15 正在尝试从 MyCollection 继承 values。当Val15 被实例化时,我试图同时调用Val10Val5value 并将它们添加到Val15values

但是,事实证明Val15 将仅继承Val10 的值,并且所有类都将调用Val10 的值。你究竟如何才能推翻这个问题?

class MyCollection(object):
    def __init__(self):
        super().__init__()
        self.values = []


class MyMessage(object):
    def __init__(self):
        super().__init__()

    def message(self):
        print('Hello World')


class Val10(object):
    def __init__(self):
        super().__init__()
        print('Call 10')
        self.values.append(self.value())

    def value(self):
        print('Value 10')
        return 10


class Val5(object):
    def __init__(self):
        super().__init__()
        print('Call 5')
        self.values.append(self.value())

    def value(self):
        print('Value 5')
        return 5


class Val15(Val10, Val5, MyMessage, MyCollection):
    def __init__(self):
        super().__init__()

    def my_sum(self):
        return sum(self.values)


val15 = Val15()
val15.my_sum()
val15.message()

# Result:
# Call 5
# Value 10
# Call 10
# Value 10
# Hello World

【问题讨论】:

  • 这是为数不多的两个前导双下划线实际上有意义的情况之一,以避免这种冲突(参见例如docs.python.org/3/tutorial/classes.html#private-variables)。
  • 我尝试对两个班级都这样做,但我仍然遇到同样的问题。
  • 问题是self总是一个Val15,所以它自己的方法是先在MRO中。在不明确的情况下(self.values.append(Val10.value(self)) 或在各个地方调用 super,这是您应该期待的行为。
  • 我认为你需要重新考虑你的类的结构。例如,val15.value() 应该打印什么,它应该返回什么值?它应该同时打印510 还是只打印15,或者这两个选项都不打印?

标签: python inheritance mixins


【解决方案1】:

这是有趣的部分:

class Val10(object):
    def value(self):
        return 10

class Val5(object):
    def value(self):
        return 5

要获得父母价值的总和,您必须调用他们每个人:

class Val15(Val10, Val5):
    def value(self):
        return Val10.value(self) + Val5.value(self)

替代解决方案

另一种方法是定义 value 总是返回所有继承值的总和,无论它们可能是什么,而不知道要调用哪个父类的 value

class Val10:
    def value(self):
        previous = getattr(super(), 'value', lambda: 0)()
        return previous + 10

class Val5:
    def value(self):
        previous = getattr(super(), 'value', lambda: 0)()
        return previous + 5

class Val15(Val10, Val5):
    def value(self):
        return getattr(super(), 'value', lambda: 0)()

Val15().value()  # 15

这个解决方案不对继承的配置方式做任何假设。

备注:

  • 答案假定这是 Python 3,因为 super() 语法
  • getattr(super(), 'value', lambda: 0) 返回父类绑定的 value 方法,如果存在的话,或者默认为返回 0 的函数。

【讨论】:

  • 我喜欢你的第一个解决方案。它;更干净
猜你喜欢
  • 2018-09-09
  • 2011-05-13
  • 2013-07-16
  • 1970-01-01
  • 2019-06-14
  • 2014-01-22
  • 2016-12-11
  • 2016-01-30
  • 1970-01-01
相关资源
最近更新 更多