标签: method-resolution-order

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
查看次数

钻石继承和 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
查看次数

django add_to_class() 使模型继承/MRO 工作出错

通过 add_to_class() 添加字段时,我的模型继承存在问题。我有一个模型File(models.Model)Image(File)-这些来自Django的文件管理器。

在我的应用程序中,我正在导入它们并添加字段和方法:

def method_x(self):
    print "x"

File.add_to_class("expiration_date", models.DateField(null=True, blank=True))
File.add_to_class("method_x", method_x)
Run Code Online (Sandbox Code Playgroud)

Image 应该继承这两个,但它只获取方法,而不是字段:

>>> some_file = File.objects.get(id=8)
>>> some_image = Image.objects.get(id=8)
>>>
>>> print some_file.expiration_date # this works
... None
>>>
>>> some_image.metgod_x() # this works
>>> x
>>>
>>> print some_image.expiration_date # and this not
Traceback (most recent call last):
    File "<console>", line 1, in <module>
AttributeError: 'Image' object has no attribute 'expiration_date'
Run Code Online (Sandbox Code Playgroud)

有什么线索吗?

django inheritance method-resolution-order

6
推荐指数
1
解决办法
6033
查看次数

为什么使用泛型的"等于"方法解析与显式调用不同

我有以下示例:

namespace ComparisonExample
{
    class Program
    {
        static void Main(string[] args)
        {
            var hello1 = new Hello();
            var hello2 = new Hello();

            // calls Hello.Equals
            var compareExplicitly = hello1.Equals(hello2);

            // calls Object.Equals
            var compareWithGenerics = ObjectsEqual<Hello>(hello1, hello2); 
        }

        private static bool ObjectsEqual<TValue>(TValue value1, TValue value2)
        {
            return value1.Equals(value2);
        }
    }

    class Hello : IEquatable<Hello>
    {
        public bool Equals(Hello other)
        {
            return true; // doesn't matter
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是为什么在第二个"Equals"调用中,我被重定向到Object.Equals而不是Hello.Equals,即使我在泛型参数中指定了确切的类型?

c# comparison method-resolution-order

6
推荐指数
1
解决办法
232
查看次数

Python和多重继承中的方法顺序

在Python中,如果使用相同的方法定义两个类并且打算将这两个类作为父类,则:

class A(object):
     def hello(self):
         print "hello from class a" 
Run Code Online (Sandbox Code Playgroud)

和:

class B(object):
     def hello(self):
         print "hello from class b"
Run Code Online (Sandbox Code Playgroud)

当您定义子类并按顺序A和B添加两个父类时:

class C(A, B):
     def __init__(self):
         self.hello()
Run Code Online (Sandbox Code Playgroud)

调用self.method()时使用的方法是属于A的方法,或继承列表中的第一个类:

>>> C()
hello from class a
<__main__.C object at 0x10571e9d0>
Run Code Online (Sandbox Code Playgroud)

虽然在我的所有测试用例中似乎都是如此,但我无法在文档或在线中找到它在任何平台和语言实现中实际上是安全的.任何人都可以确认可以安全地假设列表中的第一个继承类将始终是使用的方法(不管super().__ init __()调用等)或指向我确认这一点的官方文档?

谢谢,

python oop inheritance multiple-inheritance method-resolution-order

6
推荐指数
1
解决办法
2846
查看次数

如何从 Python 中的“super()”获取实例方法的下一行父类

我想知道从 super() 函数获得的实​​例的类型。我试着print(super())__print(type(super()))__

class Base:
    def __init__(self):
        pass

class Derive(Base):
    def __init__(self):
        print(super())        
        print(type(super()))        
        super().__init__()

d = Derive()
Run Code Online (Sandbox Code Playgroud)

结果是

<super: <class 'Derive'>, <Derive object>>
<class 'super'>
Run Code Online (Sandbox Code Playgroud)

有了这些结果,我想知道如何super().__init__()调用正确的构造函数。

python super method-resolution-order

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

mro方法和类的__mro__属性有什么区别?

mro当我使用时,我偶然发现了这种额外的,没有下划线的方法__metaclass__ = abc.ABCMeta.它似乎是相同的,__mro__除了它返回一个列表而不是一个元组.这是一个随机的例子(ideone片段):

import abc
import copy

class Life(object):
    __metaclass__ = abc.ABCMeta

    @abc.abstractmethod
    def reproduce(self):
        pass

class Bacterium(Life):
    def reproduce(self):
        return copy.deepcopy(self)

wiggly = Bacterium()

print wiggly.__class__.__mro__
# (<class '__main__.Bacterium'>, <class '__main__.Life'>, <type 'object'>)

print wiggly.__class__.mro()
# [<class '__main__.Bacterium'>, <class '__main__.Life'>, <type 'object'>]
Run Code Online (Sandbox Code Playgroud)

我后来发现这并不是唯一的,ABCMeta但在所有新式课程中都可以使用.

所以为什么?这是做什么__mro__的不是?

python abc method-resolution-order

5
推荐指数
1
解决办法
1183
查看次数

如果定义一个没有 __init__ 方法的类会发生什么?

假设我定义了四个类如下:

(该代码已经在 Python 3.6.5 上进行了测试。但是,我希望它也可以在 Python 2.7.x 上使用from __future__ import print_function

In [1]: class A(object):
   ...:     pass
   ...: 
   ...: class B(object):
   ...:     def __init__(self, value):
   ...:         print('B(value=%s)' % value)
   ...: 
   ...: class C(A):
   ...:     def __init__(self, value):
   ...:         print('C(value=%s)' % value)
   ...:         super(C, self).__init__(value)
   ...: 
   ...: class D(A, B):
   ...:     def __init__(self, value):
   ...:         print('D(value=%s)' % value)
   ...:         super(D, self).__init__(value)
   ...:         

In [2]: C.mro()
Out[2]: [__main__.C, __main__.A, object]

In [3]: D.mro()
Out[3]: …
Run Code Online (Sandbox Code Playgroud)

python multiple-inheritance method-resolution-order

5
推荐指数
1
解决办法
4530
查看次数

方法解析顺序 MRO

为什么搜索B之后,没有进一步搜索Y OR z而是去搜索A?

Y是A的父级,如果应该先搜索A,但Y是B的父级,所以应该先搜索Y,为什么这不会抛出MRO错误?

有人可以解释一下这个查找是如何工作的吗?

class X(object):pass
class Y(object): pass
class Z(object): pass
class A(X,Y): pass
class B(Y,Z):pass
class M(B,A,Z):pass
print M.__mro__
Run Code Online (Sandbox Code Playgroud)

给出

(<class '__main__.M'>, <class '__main__.B'>, <class '__main__.A'>, <class '__main__.X'>, <class '__main__.Y'>, <class '__main__.Z'>, <type 'object'>)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

python method-resolution-order

5
推荐指数
1
解决办法
2171
查看次数