2016-04-19 9 views
5

में परिभाषित प्रकार को उप-वर्गीकरण करते समय विधि को अनदेखा किया गया है, मैं कुछ मॉड्यूल और विधियों को उपनाम करने के लिए सी मॉड्यूल में परिभाषित एक प्रकार को उप-वर्गीकृत कर रहा हूं ताकि मेरी स्क्रिप्ट विभिन्न संदर्भों में काम करे।सी मॉड्यूल

यह कैसे काम करने के लिए है, मुझे अपनी कक्षा के शब्दकोश को मैन्युअल रूप से ट्विक करना है? यदि मैं डिक्शनरी में DistanceTo का संदर्भ नहीं जोड़ता, तो मुझे Point3d has no attribute named DistanceTo मिलता है।

class Point3d(App.Base.Vector): 
     def __new__(cls, x, y, z): 
      obj = super(Point3d, cls).__new__(cls) 
      obj.x, obj.y, obj.z = x, y, z 
      obj.__dict__.update({ 
       'X':property(lambda self: self.x), 
       'Y':property(lambda self: self.y), 
       'Z':property(lambda self: self.z), 
       'DistanceTo':lambda self, p: self.distanceToPoint(p)}) 
      return obj 
     def DistanceTo(self, p): return self.distanceToPoint(p) 

मैं सोच रहा था कि एक बार __new__ एक उदाहरण लौटा था मैं अभी भी तरीके और विशेषताओं के साथ पॉप्युलेट सकता है। क्या कोई इस पर रोशनी डाल सकता है ?

संपादित करें: मैं जिस मॉड्यूल से आयात करता हूं वह फ्रीकैड है। सी बेस प्रकार there परिभाषित किया गया है। तब वेक्टर ली गई है प्रपत्र इस परिभाषा here

EDIT2: मैं भी करने की कोशिश की है:

class Point3d(App.Base.Vector): 
     def __new__(cls, x, y, z): 
      obj = super(Point3d, cls).__new__(cls) 
      obj.x, obj.y, obj.z = x, y, z 
      obj.__dict__.update({ 
       'X': x, 'Y': y, 'Z': z, 
       'DistanceTo':lambda self, p: self.distanceToPoint(p)}) 
      return obj 
     def DistanceTo(self, p): return self.distanceToPoint(p) 

और एक दूसरे बिंदु बनाने के बाद, दोनों Point3d pp.X, p.Y और p.Z के लिए अंतिम बिंदु का मान देता है कोई फर्क नहीं पड़ता कि उदाहरण के निर्माण पर x,y,z पैरामीटर पारित किए गए थे। p.x, p.y, p.z अपेक्षित मान वापस करें। ऐसा लगता है कि शब्दकोश के बीच शब्दकोश साझा किया जाता है।

संपादित करें 3: समस्या हल हो गई! नीचे दिए गए उत्तर में बताए गए अनुसार subclassing को रोकने के लिए Py_TPFLAGS_BASETYPE बिट शून्य पर सेट है।

उत्तर

1

मैं PyObjectBase.cpp में जवाब मिला:

/** \brief 
* To prevent subclasses of PyTypeObject to be subclassed in Python we should remove 
* the Py_TPFLAGS_BASETYPE flag. For example, the classes App::VectorPy and App::MatrixPy 
* have removed this flag and its Python proxies App.Vector and App.Matrix cannot be subclassed. 
* In case we want to allow to derive from subclasses of PyTypeObject in Python 
* we must either reimplment tp_new, tp_dealloc, tp_getattr, tp_setattr, tp_repr or set them to 
* 0 and define tp_base as 0. 
*/ 

यह App::VectorPy वर्ग नहीं सुरक्षित रूप से उपवर्गीकरण समर्थन करने के लिए लागू किया जा रहा है और इसलिए Py_TPFLAGS_BASETYPE बिट यह को रोकने के लिए शून्य पर सेट की वजह से है होने से

जानकारी के लिए, यह bytes अंतर्निहित प्रकार की एक समान स्थिति है जिसे उप-वर्गीकृत नहीं किया जा सकता है। Guido van Rossum से सुनने के लिए यह discussion देखें क्यों bytes उप-वर्गीकरण योग्य नहीं है।

+0

मुझे लगता है कि यह एक वैध उत्तर है, लेकिन मैं यहां के बजाय एक नए प्रश्न में अनुवर्ती प्रश्न पूछने की सलाह दूंगा। – MSeifert

+0

क्षमा करें मैं थोड़ा सा शोध करने के बाद एक नया प्रश्न खोलूंगा। –

2

मुझे समझ में नहीं आता कि आप गुणों को गतिशील रूप से क्यों जोड़ना चाहते हैं। बस का उपयोग करें:

class Point3d(App.Base.Vector): 
    def __init__(self, x, y, z): 
     super().__init__(x, y, z) # or maybe super().__init__([x, y, z]) 

    @property 
    def X(self): 
     return self[0] # guessing that App.Base.Vector works like a list 

    @property.setter 
    def X(self, value): 
     self[0] = value 

    # Y and Z likewise. 
+0

बिल्कुल, मैंने पहले कोशिश की लेकिन मुझे 'प्वाइंट 3 डी' एक्स 'नामक कोई विशेषता नहीं मिली है। मुझे समझ में नहीं आ रहा है कि मुझे ऐसा करने के लिए हुड के नीचे क्यों जाना है ... –

+1

@ जैक्यूस गौडिन: अपना इंडेंटेशन जांचें और इसे फिर से प्रयास करें। आपने शायद संपत्तियों को गलत तरीके से इंडेंट किया है। – user2357112

+0

यह सुझाव देने के लिए धन्यवाद। इंडेंटेशन सही है, मेरी फाइल में सभी रिक्त स्थान, लेकिन कॉपी-पेस्ट ऑपरेशन के दौरान पीड़ित थे। –

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