标签: method-resolution-order

如果在层次结构中混合旧样式类和新样式类会发生什么?

假设你有类似的东西

class C2: pass
class C1(object): pass
class B2: pass
class B1(C1, C2): pass
class A(B1,B2): pass
Run Code Online (Sandbox Code Playgroud)

当您具有混合层次结构时,python如何相对于继承和方法解析顺序?它是否遵循旧的遍历,新的遍历,两者的混合取决于层次结构的哪个分支行走?

python multiple-inheritance method-resolution-order

10
推荐指数
1
解决办法
351
查看次数

为什么__mro__没有显示在dir(MyClass)中?

class MyClass(object):
    pass

print MyClass.__mro__
print dir(MyClass)
Run Code Online (Sandbox Code Playgroud)

输出:

(<class '__main__.MyClass'>, <type 'object'>)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
Run Code Online (Sandbox Code Playgroud)

为什么__mro__没有列出dir()

python method-resolution-order

9
推荐指数
2
解决办法
2769
查看次数

在多重继承的情况下,super方法如何在python中工作?

超级方法如何在python中实际运行?

在给定的代码中:

class A(object):
    def test(self):
        return 'A'


class B(A):
    def test(self):
        return 'B->'+super(B, self).test()


class C(A):
    def test(self):
        return 'C'


class D(B,C):
    pass


print B().test()    # B->A
print D().test()    # B->C  ????

# MRO of classes are as
print 'mro of A', A.__mro__   # [A,object]
print 'mro of B', B.__mro__   # [B,A,object]
print 'mro of C', C.__mro__   # [C,A,object]
print 'mro of D', D.__mro__   # [D,B,C,A,object]
Run Code Online (Sandbox Code Playgroud)

test在D上调用时,它输出B->C而不是B->A(我期待的).

B中的超级内容如何引用C的实例?

python oop inheritance multiple-inheritance method-resolution-order

8
推荐指数
1
解决办法
162
查看次数

functools.singledispatch等效于super()

functools.singledispatch有助于定义单调度泛型方法.同时,还有super()调用方法或访问超类的属性.

是否有类似的东西super()可以使用singledispatch?我尝试了以下,但结果super(Derived, value)只是不是实例Base,所以它不能按我的预期工作:

from functools import singledispatch

@singledispatch
def hello(value):
    return ['default']

@hello.register(Base)
def hello_base(value):
    return hello(super(Base, value)) + ['base']

@hello.register(Derived)
def hello_derived(value):
    return hello(super(Derived, value)) + ['derived']

print(hello(Derived())
# expected ['default', 'base', 'derived'],
# but actually is ['default', 'derived'].
Run Code Online (Sandbox Code Playgroud)

python super method-resolution-order python-3.x functools

8
推荐指数
1
解决办法
181
查看次数

为什么在MRO中以这种方式订购课程?

我有Python MRO的问题对于这段代码:

class F: pass 
class G: pass 
class H: pass
class E(G,H): pass
class D(E,F): pass 
class C(E,G): pass
class B(C,H): pass
class A(D,B,E): pass

print(A.__mro__)
Run Code Online (Sandbox Code Playgroud)

我得到这个输出:

(<class '__main__.A'>, <class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.E'>, <class '__main__.G'>, <class '__main__.H'>, <class '__main__.F'>, <class 'object'>)

我为什么要来<class '__main__.C'>之前<class '__main__.E'>

我以为会是:

  1. A
  2. D,B,E
  3. E,F| C,H| G,H

等等

python class multiple-inheritance method-resolution-order python-3.x

8
推荐指数
1
解决办法
562
查看次数

如果将基类的可选功能存储在二级类中,二级类是否应该继承基类?

我知道标题可能有点混乱,所以让我举个例子。假设您有一个基类Base,它旨在被子类化以创建更复杂的对象。但是您还有一些可选功能,您不需要每个子类都需要这些功能,因此您将它放在一个二级类中OptionalStuffA,该二级类始终打算与基类一起进行子类化。你也应该让那个次要类成为 的子类Base吗?

这当然是唯一相关,如果你有一个以上的OptionalStuff班,你想给他们以不同的方式结合起来,否则你不需要子类均BaseOptionalStuffA(,只是有OptionalStuffA成为的一个子类Base,所以你只需要在子类OptionalStuffA)。我Base知道如果从Base.

下面是一个示例场景。我还将QObject该类作为“第三方”令牌类放入该类,其功能对于其中一个辅助类工作是必需的。我在哪里子类化它?下面的例子显示了我到目前为止是如何做到的,但我怀疑这是要走的路。

from PyQt5.QtCore import QObject

class Base:
    def __init__(self):
        self._basic_stuff = None

    def reset(self):
        self._basic_stuff = None


class OptionalStuffA:
    def __init__(self):
        super().__init__()
        self._optional_stuff_a = None

    def reset(self):
        if hasattr(super(), 'reset'):
            super().reset()
        self._optional_stuff_a = None

    def do_stuff_that_only_works_if_my_children_also_inherited_from_Base(self):
        self._basic_stuff = not None


class OptionalStuffB:
    def __init__(self):
        super().__init__()
        self._optional_stuff_b = None

    def reset(self):
        if hasattr(super(), 'reset'): …
Run Code Online (Sandbox Code Playgroud)

python multiple-inheritance method-resolution-order

8
推荐指数
1
解决办法
228
查看次数

python3 super不能与PyQt类一起使用

python3中有一个简单的程序:

from PyQt4 import QtCore
import PyQt4

class Bar(object):
    def __init__(self):
        print("Bar start")
        super(Bar, self).__init__()
        print("Bar end")

class FakeQObject(object):
    def __init__(self):
        print("FakeQObject start")
        super(FakeQObject, self).__init__()
        print("FakeQObject end")

class Foo(QtCore.QObject, Bar):
#class Foo(FakeQObject, Bar):
    def __init__(self):
        print("Foo start")
        super(Foo, self).__init__()
        print("Foo end")


print(Foo.__mro__)
print(PyQt4.QtCore.PYQT_VERSION_STR)
f = Foo()
Run Code Online (Sandbox Code Playgroud)

a)当类Foo继承自QtCore.QObject和Bar时,我们得到:

(<class '__main__.Foo'>, <class 'PyQt4.QtCore.QObject'>, <class 'sip.wrapper'>, <class 'sip.simplewrapper'>, <class '__main__.Bar'>, <class 'object'>)
4.9.4
Foo start
Foo end
Run Code Online (Sandbox Code Playgroud)

b)当类Foo继承自FakeQObject和Bar时,我们得到:

(<class '__main__.Foo'>, <class '__main__.FakeQObject'>, <class '__main__.Bar'>, <class 'object'>)
4.9.4
Foo start
FakeQObject start
Bar start …
Run Code Online (Sandbox Code Playgroud)

pyqt4 method-resolution-order python-3.x

7
推荐指数
1
解决办法
686
查看次数

在运行时更改python mro

我发现自己处于一种不寻常的情况,我需要在运行时更改类的MRO.

代码:

class A(object):
    def __init__(self):
        print self.__class__
        print "__init__ A"
        self.hello()

    def hello(self):
        print "A hello"

class B(A):
    def __init__(self):
        super(B, self).__init__()
        print "__init__ B"
        self.msg_str = "B"
        self.hello()

    def hello(self):
        print "%s hello" % self.msg_str

a = A()
b = B()
Run Code Online (Sandbox Code Playgroud)

正如预期的那样,这失败了,因为__init__A 的方法(当从B调用时)调用B hello,它试图在属性存在之前访问它.

问题在于我可以做出的改变受到限制:

  • B必须是A的子类
  • A不能改变
  • A和B都需要hello方法
  • 在调用super之前,B无法初始化其他属性 __init__

我确实通过在运行时更改MRO来解决这个问题.简而言之,在B期间__init__,但在调用super之前__init__,MRO将被更改,以便首先搜索A的方法,从而调用A hello而不是B(因此失败).

问题是MRO是只读的(在类运行时).

还有其他方法可以实现吗?或者可能完全不同的解决方案(仍然尊重上述约束)?

python class method-resolution-order

7
推荐指数
1
解决办法
4174
查看次数

钻石继承和 MRO

我是 MRO 的新手,在弄清楚这些输出的逻辑时遇到了问题。

情况1:

class A(object):
  def save(self):
      print "A"

class B(A):
    def save(self):
        print "B"
        super(B, self).save()

class C(A):
  def save(self):
      print "C"
      super(C, self).save()


class D(C, B):
    def save(self):
        print "D"
        super(D,self).save()

D().save()
Run Code Online (Sandbox Code Playgroud)

输出:

class A(object):
  def save(self):
      print "A"

class B(A):
    def save(self):
        print "B"
        super(B, self).save()

class C(A):
  def save(self):
      print "C"
      super(C, self).save()


class D(C, B):
    def save(self):
        print "D"
        super(D,self).save()

D().save()
Run Code Online (Sandbox Code Playgroud)

我的问题是如何super(C)调用B.save().

根据 MRO:super(C, self)不是关于“的基类C”,而是关于 MRO …

python method-resolution-order

7
推荐指数
1
解决办法
1165
查看次数

具有抽象方法的 Python mixin 会覆盖具体方法

两个 mixin 类将需求指定为抽象方法。这些类共同拥有一整套具体方法。然而,它们无法组合成一个具体的类:无论我使用哪种顺序来声明具体的类,一些抽象方法都会覆盖具体的方法。

有没有办法防止抽象方法覆盖具体方法?我相信这在 Scala 中是有效的。

指定要求的替代方法有哪些?

这是一个具体的例子:

import abc


class A(abc.ABC):
    @abc.abstractmethod
    def x(self):
        pass

    def y(self):
        return "A.y"


class B(abc.ABC):
    @abc.abstractmethod
    def y(self):
        pass

    def x(self):
        return f"B.x"


class AB(B, A):
    pass


class BA(A, B):
    pass


ab = AB()  # TypeError: Can't instantiate abstract class AB with abstract methods y

ba = BA()  # TypeError: Can't instantiate abstract class BA with abstract methods x
Run Code Online (Sandbox Code Playgroud)

python multiple-inheritance mixins method-resolution-order

7
推荐指数
1
解决办法
380
查看次数