मेरे पास आंशिक रूप से साइथन में लिखा गया एक पायथन एक्सटेंशन है। मेरी समस्या यह है कि, अगर मैं साइथन कोड में पाइथन ऑब्जेक्ट्स को तुरंत चालू करता हूं, तो बंदर पैचिंग को अनदेखा कर दिया जाता है।

छद्म कोड mymodule.pyx:

cdef class ABC():
    pass    # some methods here...

cdef class DEF():
    def method1(self):
        return ABC(...)

अजगर कोड में बंदर-पैचिंग का छद्म कोड:

import mymodule as mm

class GHI(mm.ABC):
    pass

mm.ABC_ = mm.ABC
mm.ABC = GHI

def = mm.DEF(...)
ret_val = def.method1(...)

ret_value का प्रकार GHI के बजाय < class 'mymodule.ABC'> है।

साइथन परिभाषित कक्षाओं को बंदर-पैच करने योग्य बनाने के बारे में कोई सलाह?

1
ARF 5 सितंबर 2019, 17:51

1 उत्तर

सबसे बढ़िया उत्तर

आपको यह सुनिश्चित करने की आवश्यकता है कि ABC केवल एक मॉड्यूल-स्तरीय चर है, न कि cdef class

cdef class _ABC():
    pass    # some methods here...

ABC = _ABC

फिर आप mm.ABC को फिर से असाइन कर सकते हैं, हालांकि आप इसे पसंद करते हैं। यह स्पष्ट रूप से कक्षा को प्रारंभ करते समय साइथन द्वारा किए गए कुछ छोटे अनुकूलन को हटा देता है, लेकिन यह लचीलेपन के लिए व्यापार-बंद है।

यदि आपको _ABC की cdef विशेषताओं तक पहुंचने की आवश्यकता है, तो यह करें:

cdef class DEF_(): # underscore to avoid using Cython DEF keyword
    def method1(self):
        cdef _ABC inst = ABC(...)
        inst.cdef_attribute = ... # works fine

यह एक रनटाइम त्रुटि उत्पन्न करेगा यदि ABC का परिणाम _ABC नहीं है (उपवर्ग हालांकि ठीक हैं)

3
DavidW 6 सितंबर 2019, 11:25