首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用子类MRO继承别名

使用子类MRO继承别名
EN

Stack Overflow用户
提问于 2018-03-23 22:59:04
回答 3查看 137关注 0票数 4
代码语言:javascript
复制
class parent:
    def fun1(self):
        print("foo")

    fun2 = fun1

class child(parent):
    def fun1(self):
        print("bar")

child().fun2()

此代码输出"foo“。我非常肯定我理解为什么会发生这种情况,但我想知道是否有一种直接的方法来实现我想要的东西(根据MRO行为的可继承别名,因此它输出"bar"),或者为什么这是糟糕的编程实践。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2018-03-23 23:19:52

没有办法直接做你想做的事。

要理解为什么,您需要了解方法查找的工作方式。它在描述符HOWTO中得到了详细的解释,我试图编写一个不那么专家级别的解释这里,所以我假设您阅读了这两种解释,并展示了它们的效果:

代码语言:javascript
复制
>>> child.fun1
<function __main__.child.fun1>
>>> child.fun2
<function __main__.parent.fun1>
>>> child().fun2
<bound method parent.fun1 of <__main__.child object at 0x10b735ba8>>

注意,child.fun2parent.fun1,而不是child.fun1。这解释了为什么child().fun2最终成为parent.fun1周围的绑定方法,即使self最终成为child实例。为什么?显然,fun2不在child.__dict__中(或者我们不需要MRO)。在parent.__dict__中,它只能是parent.fun1

那么,解决办法是什么呢?

您可以像Patrick建议的那样,将fun2变成转发给fun2property。或者你可以这么做:

代码语言:javascript
复制
def fun2(self):
    return self.fun1()

这个解决方案的好处是非常简单--任何会Python的人都会理解它的工作原理。

但是Patrick的解决方案的优点不仅仅是child().fun2(),还有child().fun2 (作为一个可以传递的对象,比较身份,等等)。按你想要的方式工作。

同时,有一个与您所要求的内容密切相关的成语,其中一组您不希望覆盖的公共方法称为您所做的“受保护”实现方法。例如,一个简单的一维数组-数学类可能会这样做:

代码语言:javascript
复制
def _math(lhs, rhs, op):
    # not actually a useful implementation...
    return [op(x, y) for x, y in zip(lhs, rhs)] 
def __add__(self, other):
    return self._math(other, add)
def __radd__(self, other):
    return self._math(other, add)
# etc.

现在__add____radd__之间没有不对称,只有“公共”接口(__add____radd__)和“受保护的”接口(_math)之间不对称。

票数 4
EN

Stack Overflow用户

发布于 2018-03-24 01:24:37

这里有一个非常简单的方法--这是完全可以的:

代码语言:javascript
复制
class Parent:
    def fun1(self):
        print("foo")

    def fun2(self):
        return self.fun1()


class Child(Parent):
    def fun1(self):
        print("bar")


Child().fun2()  # -> bar
票数 3
EN

Stack Overflow用户

发布于 2018-03-23 23:11:35

可以让fun2成为返回self.fun1的属性。

代码语言:javascript
复制
class Parent:
    def fun1(self):
        print('foo')
    @property
    def fun2(self):
        return self.fun1

class Child(Parent):
    def fun1(self):
        print('bar')

Child().fun2()
# bar
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49459370

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档