2012-09-10 27 views
7

Có một chương trình đơn giản trong python3:python3 siêu không làm việc với các lớp PyQt

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() 

a) Khi lớp Foo thừa hưởng từ QtCore.QObject và Bar chúng tôi nhận được:

(<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 

b) Khi lớp Foo thừa hưởng từ FakeQObject và Bar chúng tôi nhận được:

(<class '__main__.Foo'>, <class '__main__.FakeQObject'>, <class '__main__.Bar'>, <class 'object'>) 
4.9.4 
Foo start 
FakeQObject start 
Bar start 
Bar end 
FakeQObject end 
Foo end 

câu hỏi đặt ra là: tại sao trong a) trường hợp, Bar init không được gọi?

Tôi tìm thấy câu hỏi tương tự ở đây pyQt4 and inheritance nhưng không có câu trả lời hay.

Cảm ơn trước!

+4

Tôi nghi ngờ đó là vì 'QtCore.QObject' không sử dụng hợp tác super.'__init__'. BTW, trong Python 3, bạn không cần 'siêu (Foo, tự)'; 'super()' là đủ. – nneonneo

+0

Có, nhưng trang web PyQt http://www.riverbankcomputing.co.uk/static/Docs/PyQt4/html/gotchas.html cho biết: "Trong các phiên bản PyQt sớm hơn v4.5 có các hạn chế về việc sử dụng siêu dữ liệu Các lớp PyQt. Các hạn chế này không còn áp dụng với v4.5 trở lên nữa. " Vì vậy, đây là một lỗi của PyQt, phải không? – vitvlkv

+0

Cảm ơn siêu() không có thông số, không biết về nó .. – vitvlkv

Trả lời

3

Cùng với @nneonneo Tôi cũng nghi ngờ rằng QtCore.QObject không sử dụng hợp tác xã super.__init__. Nếu nó đã làm, bạn sẽ không có vấn đề này.

Tuy nhiên, bạn nên lưu ý rằng tại một số điểm, một trong các lớp cơ sở không thể sử dụng hợp tác siêu vì object sẽ không có phương pháp. Xem xét:

class Base(): 
    def __init__(self): 
     print("initializing Base") 
     super().__init__() 
    def helper(self, text): 
     print("Base helper") 
     text = super().helper(text) 
     text = text.title() 
     print(text) 

class EndOfTheLine(): 
    def __init__(self): 
     print("initializing EOTL") 
     super().__init__() 
    def helper(self, text): 
     print("EOTL helper") 
     text = super().helper(text) 
     return reversed(text) 

class FurtherDown(Base, EndOfTheLine): 
    def __init__(self): 
     print("initializing FD") 
     super().__init__() 
    def helper(self, text): 
     print(super().helper(text)) 

test = FurtherDown() 
print(test.helper('test 1 2 3... test 1 2 3')) 

và đầu ra:

initializing FD 
initializing Base 
initializing EOTL 
Base helper 
EOTL helper 
Traceback (most recent call last): 
    File "test.py", line 28, in <module> 
    print(test.helper('test 1 2 3... test 1 2 3')) 
    File "test.py", line 25, in helper 
    print(super().helper(text)) 
    File "test.py", line 7, in helper 
    text = super().helper(text) 
    File "test.py", line 17, in helper 
    text = super().helper(text) 
AttributeError: 'super' object has no attribute 'helper' 

Vì vậy, tùy theo lớp học sẽ được kết thúc của Line cần không gọi super. Vì có các phương thức khác Qt mà bạn có thể muốn ghi đè, điều đó quy định rằng lớp Qt phải là lớp cuối cùng trong tiêu đề lớp. Bởi không có __init__ sử dụng hợp tác siêu, mặc dù nó có thể, Qt là tránh lỗi tiếp tục xuống khi một số phương pháp khác được ghi đè.

Các vấn đề liên quan