2013-12-09 6 views
5

मेरे पास एक संवाद वर्ग है जो एक पाइसाइड-यूआईसी-जेनरेटेड पायथन कक्षा विरासत में है लेकिन मेरी समस्या यह है कि इसे एक और बेस क्लास जोड़ने के लिए विस्तारित नहीं किया जा सकता है।पायसाइड, पीसाइडयूआईसी और एकाधिक विरासत

import sys 
from PySide import QtGui 
from mi_ui import Ui_Dialog 

class Worker(object): 
    def __init__(self): 
     super(Worker, self).__init__() 
     self.data = 1 

class MainDialog(QtGui.QDialog, Ui_Dialog, Worker): 
    def __init__(self): 
     super(MainDialog, self).__init__() 
     self.setupUi(self) 

if __name__ == '__main__': 
    app = QtGui.QApplication(sys.argv) 
    dlg = MainDialog() 
    print dlg.data 
    dlg.show() 

    sys.exit(app.exec_()) 

जब मैं Worker साथ MainDialog का विस्तार करने की कोशिश, सुपर फोन नहीं करता है Worker के __init__ और प्रिंट dlg.data में विफल रहता है, क्योंकि "AttributeError: '

MainDialog डेटा' 'वस्तु कोई गुण नहीं है'"

मेरा एकमात्र काम सुपर को अनदेखा करता है और मैन्युअल रूप से प्रत्येक __init__ को आमंत्रित करता है।

QtGui.QDialog.__init__(self) 
Worker.__init__(self) 

क्या यह मेरा एकमात्र समाधान है?

यह पायथन 2.7 के लिए है।

+0

जहां तक ​​मेरा अनुभव चिंतित है, 'सुपर() 'क्यूटी के लिए पाइसाइड रैपर के साथ काम नहीं करता है, और मुझे विश्वास नहीं है कि पीईक्यूटी यहां कोई अलग है। इसलिए '__init__' मैन्युअल रूप से कॉल करना आपका एकमात्र तरीका हो सकता है। केवल हीरे के आकार के उत्तराधिकारों से बचने (या आसपास काम करने) सुनिश्चित करना सुनिश्चित करें। – quazgar

उत्तर

1

पाइथन में एकाधिक विरासत मुश्किल है। जिन वर्गों से आप विरासत में हैं, उन्हें कोई संघर्ष नहीं हो सकता है यदि आप इसे पूरी तरह से काम करना चाहते हैं। ज्यादातर मामलों में पाइसाइड के साथ कई विरासत एक संघर्ष का कारण बनती है क्योंकि सबकुछ QObject को समान चर और विधियों को देता है। पाइथन को पता नहीं है कि कौन सा वारिस है। चित्रकला संघर्ष के लिए एक और क्षेत्र है। विचार करने की दूसरी बात विरासत का आदेश है। मेरा मानना ​​है कि अजगर विरासत और बाएं से दाएं में प्रवेश करता है। इसलिए यदि आप केवल QtGui.QDialog और वर्कर (Ui_Dialog शायद संघर्ष करेंगे) के लिए init विधि चाहते हैं तो आप कोशिश करना चाहेंगे।

class MainDialog(QtGui.QDialog, Worker, Ui_Dialog): 

पायथन 3 में आप सुपर विधि को थोड़ा अलग तरीके से कॉल कर सकते हैं।

class MainDialog(QtGui.QDialog, Worker, Ui_Dialog): 
    super().__init__() 

मेरा मानना ​​है कि जिस तरह से आप 2.7 के लिए init बुला रहे हैं, वह चीजों को करने का सही तरीका है। इस तरह के प्रश्न सभी जगह पर हैं। यह एक आम समस्या है जिसे Diamond problem के नाम से जाना जाता है। Python super method and calling alternatives चीजों को थोड़ा और समझा सकता है।

+0

लेकिन ध्यान दें कि 'सुपर()' केवल घोषणा के रूप में कार्य करता है अगर पूर्वजों ने अपने रचनाकारों को उचित रूप से लागू किया है (जैसे '** कीवर्ड' स्वीकार करना और इसे अगले 'सुपर() 'पर अग्रेषित करना)।यह क्यूटी कक्षाओं के पायसाइड रैपर के लिए मामला प्रतीत नहीं होता है। – quazgar

1

बनाओ Worker पहले आधार स्तरीय:

class MainDialog(Worker, QtGui.QDialog, Ui_Dialog) 

यह अभी भी MainDialog.__init__ में परिणाम होगा पहले बुलाया जा रहा है, तो Worker.__init__ (जो अगर आप कुछ प्रिंट बयान जोड़ने देख सकते हैं)। लेकिन आप अभी भी MainDialog.__init__ के अंदर से data विशेषता तक पहुंच पाएंगे।

Ui_Dialog कक्षा वास्तव में इनमें से किसी में भी नहीं आती है, क्योंकि यह object से विरासत में केवल एक साधारण पायथन वर्ग है और कभी भी super पर कॉल नहीं करता है। तो यह बेस-क्लास ऑर्डर में कहीं भी आपको पसंद हो सकता है।

जाहिर है, यदि आप इस तरह से काम करते हैं, तो आपको Worker कक्षा में अन्य बेस-क्लास से किसी भी तरीके से छेड़छाड़ न करने की देखभाल करनी होगी - लेकिन आपके पास पहले से ही "समस्या" थी (बस एक अलग क्रम में)।

संबंधित मुद्दे