दिलचस्प पोस्ट
बाकी एपीआई प्रमाणीकरण मैं दूरी में कैसे माप सकता हूं और जावा में दो अक्षांश + अक्षांश अंक के आधार पर एक बाउंडिंग बॉक्स बना सकता हूं? एचटीएमएल 5 कैनवास आईआईएमएजेडाटा और समान उत्पत्ति नीति जावास्क्रिप्ट मैपिंग टच इवेंट्स को माउस इवेंट्स में लॉलीपॉप में ऐप मैच करने के लिए स्टेटस बार का रंग कैसे बदल सकता है? HTTPS / SSL पर जावा क्लाइंट प्रमाण पत्र जावास्क्रिप्ट के साथ शब्दों में अंकों को परिवर्तित करें लुमेन के साथ NotFoundHttpException मल्टिकास्ट (यूडीपी) सॉकेट को बाँधने का क्या मतलब है? फोनगाप कॉर्डोबा स्थापना विंडोज पूर्ण कॉलबैक के साथ jQuery के लोडिंग चित्र एक्शन बार पर ड्रॉपडाउन आइटम कैसे जोड़ें C ++ 0x के लैम्ब्डा को कैप्चर-बाय-वैल्यू के लिए डिफ़ॉल्ट रूप से "अस्थिर" कीवर्ड क्यों मिलता है? मैं जावा में डबल से दो दशमलव स्थानों को कैसे गोल करूं? देशी एंड्रॉइड ब्राउज़र के लिए प्लगइन्स कैसे विकसित करें

ट्रिपल वारसा मेटाक्लास संघर्ष का कारण बनता है … कभी-कभी

ऐसा लगता है कि मैंने एक मेटाकल्स नरक पर ठोकर खाई थी, तब भी जब मैं इसके साथ कुछ नहीं करना चाहता था।

मैं PySide का उपयोग करते हुए Qt4 में एक ऐप लिख रहा हूं। मैं यूआई परिभाषा से इवेंट-संचालित भाग को अलग करना चाहता हूं, जो क्यूटी डिजाइनर फाइलों से उत्पन्न होता है। इसलिए मैं एक "नियंत्रक" वर्ग बना रहा हूं, परन्तु मेरी जिंदगी को कम करने के लिए मैं उन्हें कई तरह से वंचित करता हूं। एक उदाहरण:

class BaseController(QObject): def setupEvents(self, parent): self.window = parent class MainController(BaseController): pass class MainWindow(QMainWindow, Ui_MainWindow, MainController): def __init__(self, parent=None): super(MainWindow, self).__init__(parent) self.setupUi(self) self.setupEvents(self) 

उम्मीद है कि यह काम करता है इसके पास से विरासत भी है ( QDialog , Ui_Dialog , BaseController ) लेकिन जब मैं BaseController उप- BaseController हूं और उप-वर्ग ( BaseController स्थान पर) से वारिस करने का प्रयास करता हूं, तो मुझे एक त्रुटि मिलती है:

TypeError: metaclass के आधार metaclass विवाद कॉल करते समय त्रुटि: एक व्युत्पन्न वर्ग के मेटाकैलास अपने सभी ठिकानों के मेटाक्लासेस का एक (गैर-सख्त) उपवर्ग होना चाहिए

स्पष्टीकरण: QMainWindow और QDialog दोनों QMainWindow से QObjectBaseController को क्यूटी इवेंट सिस्टम एक्सक्यूरिटी के कारण भी इसे से वारिस होना चाहिए। Ui_ वर्ग केवल सरल पायथन ऑब्जेक्ट क्लास से प्राप्त होते हैं। मैंने समाधान के लिए खोज की है, लेकिन उनमें से सभी जानबूझकर मेटैक्लास का इस्तेमाल करते हैं। इसलिए मुझे बहुत कुछ गलत करना चाहिए।

संपादित करें: ग्राफ़ को जोड़कर मेरा विवरण स्पष्ट हो सकता है

कार्य का उदाहरण:

 QObject | \___________________ | object | QMainWindow | BaseController | /---Ui_MainWindow | | | MainController MainWindow-----------------/ 

एक अन्य उदाहरण:

 QObject | \___________________ | object | QDialog | BaseController | /---Ui_OtherWindow | | | | OtherWindow----------------/ 

उदाहरण काम नहीं कर रहा है:

 QObject | \___________________ | object | QDialog | BaseController | /---Ui_OtherWindow | | | OtherController OtherWindow----------------/ 

Solutions Collecting From Web of "ट्रिपल वारसा मेटाक्लास संघर्ष का कारण बनता है … कभी-कभी"

त्रुटि संदेश यह इंगित करता है कि आपके दो-दूसरे पर आधारित मेटैक्लास आपके पदानुक्रम में कहीं है यह पता लगाने के लिए कि संघर्ष कहां है, आपको अपनी कक्षाओं और क्यूटी कक्षाओं में से प्रत्येक की जांच करने की आवश्यकता है।

यहां कुछ सरल उदाहरण कोड दिया गया है जो समान स्थिति सेट करता है:

 class MetaA(type): pass class MetaB(type): pass class A: __metaclass__ = MetaA class B: __metaclass__ = MetaB 

हम उन दोनों वर्गों को सीधे उप-वर्ग नहीं बना सकते, क्योंकि अजगर को पता नहीं होगा कि किस मेटाक्लास का उपयोग करना है:

 >>> class Broken(A, B): pass ... Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: Error when calling the metaclass bases metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases 

हमें यह बताने की क्या गुंजाइश है कि हमें दो मेटैक्लास के बीच एक तीसरा मेटाक्लास शुरू करने से संघर्ष को हल करने की जरूरत है जो कि आधार वर्गों से सभी मेटाक्लास के उप-वर्ग है।

मुझे यकीन नहीं है कि त्रुटि संदेश से कोई भी स्पष्ट है, लेकिन मूल रूप से, आप ऐसा करके इसे ठीक कर सकते हैं:

 class MetaAB(MetaA, MetaB): pass class Fixed(A, B): __metaclass__ = MetaAB 

यह कोड अब ठीक से संकलित और चलाता है बेशक, वास्तविक स्थिति में, आपका संघर्ष-समाधान करने वाले मेटैक्लास को यह निर्णय करना होगा कि अभिभावक मेटैक्लास के व्यवहार को किस प्रकार अपनाना है, जिसे आपको अपने आवेदन की आवश्यकताओं से खुद का पता लगाना होगा।

ध्यान रखें कि आपका विरासत वर्ग केवल दो मेटैक्लास में से एक है। __init__ पद्धतियाँ, जो कभी-कभी सभी काम करते हैं, इसलिए कई मामलों में, आपको एक __init__ जोड़ना होगा जो किसी भी तरह से कॉल करता है जिससे उन्हें साथ में मिल सके।

हम इस तरह से कुछ का उपयोग करते हैं:

 class CooperativeMeta(type): def __new__(cls, name, bases, members): #collect up the metaclasses metas = [type(base) for base in bases] # prune repeated or conflicting entries metas = [meta for index, meta in enumerate(metas) if not [later for later in metas[index+1:] if issubclass(later, meta)]] # whip up the actual combined meta class derive off all of these meta = type(name, tuple(metas), dict(combined_metas = metas)) # make the actual object return meta(name, bases, members) def __init__(self, name, bases, members): for meta in self.combined_metas: meta.__init__(self, name, bases, members) 

अच्छा, आधुनिक मेटैक्लास कार्यान्वयन स्वच्छता (जहां मेटैक्लास उपवर्ग type , और जो कुछ भी __init__ में किया जा सकता है वहां किया जाता है) को मानते हुए यह कई मेटाक्लास को साथ में लाने की अनुमति देता है

Metaclasses जो वास्तव में और जरूरी __new__ में उनके अधिकांश काम करते हैं, वे किसी भी तरह से गठबंधन करना कठिन हो रहे हैं। आप उनमें से एक को यहां सुनिश्चित करके सुनिश्चित कर सकते हैं कि इसकी कक्षा कई विरासत में पहला तत्व है।

इसका उपयोग करने के लिए, आप केवल घोषणा करते हैं:

 __metaclass__ = CooperativeMeta 

उन कक्षाओं के लिए जहां विभिन्न मेटाक्लास एक साथ आते हैं

इस मामले में, उदाहरण के लिए:

 class A: __metaclass__ = MetaA class B: __metaclass__ = MetaB class Fixed(A, B): __metaclass__ = CooperativeMeta 

यह संकलक को बंद करने के लिए अलग-अलग मेटा और मेटाबी के लिए सही तरीके से काम करने की संभावना कई गुना अधिक है, जो कि उन्हें एक साथ विरासत में मिला है।

उम्मीद है कि यह कोड कोड को समझाता है। सिर्फ एक मुश्किल रेखा है, और यह विभिन्न स्थानों से विरासत में मिली किसी भी दिए गए __metaclass__ को बेमानी कॉलों को दूर करने और अन्य लोगों के साथ अच्छी तरह से खेलने के लिए स्पष्ट __metaclass__ वर्गों को अनुमति नहीं देता है। यदि यह अतिरेखा लगता है, तो आप इसे छोड़ सकते हैं और अपने कोड में, बस कक्षाओं को ध्यान से व्यवस्थित कर सकते हैं

यह समाधान तीन पंक्तियां बनाता है और बहुत स्पष्ट है।