2016-01-02 3 views
5

पर क्लोजर मैं हाल ही में संकलन के दौरान कक्षा के लिए symbol table entry को देखकर, सीपीथन स्रोत कोड के माध्यम से कदम उठा रहा था।__class__

मैं typedef struct _symtable_entry संरचना के लिए निम्नलिखित प्रविष्टि टकरा:

[-- other entries --] 
unsigned ste_needs_class_closure : 1; /* for class scopes, true if a 
             closure over __class__ 
             should be created */ 
[-- other entries --] 

मैं वास्तव में यह समझ नहीं कर पा रहे और अजगर कोड है कि वास्तव में सेट ste_needs_class_closure == 1 का एक उदाहरण नहीं मिल सकता है।

class foo: 
    y = 30 
    def __init__(self): 
     self.x = 50 
    def foobar(self): 
     def barfoo(): 
      print(self.x) 
      print(y) 
     return barfoo 

लेकिन फिर भी वह निष्पादित निष्पादन के दौरान ste_needs_class_closure का मूल्य 0 और नहीं 1 के रूप में मैं आशा व्यक्त की यह होगा है: अन्य असफल प्रयासों के अलावा, मैं निम्नलिखित की कोशिश की है।

फ़ंक्शन जो वास्तव में इस मान को बदलता है drop_class_free है जो अधिक मदद नहीं करता है। दुर्भाग्यवश, इसमें कोई टिप्पणी नहीं है।

यह वास्तव में की एक टिप्पणी के साथ analyze_block में प्रयोग किया जाता है:

/* Check if any local variables must be converted to cell variables */ 

कौन सा मैं एक अवधारणा के रूप में समझ सकते हैं लेकिन एक उदाहरण है जहां ऐसा होता नहीं मिल रहा।

मैंने the changelog for Python 3.4 खोज करने का प्रयास किया है, संस्करण जिसमें यह सदस्य पहले दिखाई दिया था, लेकिन इसका कोई संदर्भ नहीं मिला।

तो, क्या कोई यह बता सकता है कि __class__ पर बंद होने का क्या अर्थ है, जब कक्षा के स्थानीय चर सेल चर में परिवर्तित हो जाते हैं? आदर्श रूप में, एक उदाहरण जो निष्पादन के दौरान वास्तव में इस व्यवहार को दृश्यमान बनाता है वह अद्भुत होगा।

उत्तर

2

Github’s blame view for that line of code हमें पता चलता है कि यह this commit, जो संदर्भ देता Issue #12370 में जोड़ा गया: __class__ बंद में हस्तक्षेप करने से वर्ग निकायों रोकें।

बग रिपोर्ट से, समस्या यह तय करने के लिए कोशिश कर रहा था के प्रकार का एक उदाहरण है:

अजगर 3 निम्नलिखित कोड प्रिंट False में क्योंकि super() के उपयोग __class__ वर्णनकर्ता होने के लिए कारण बना हुआ है कक्षा नामस्थान से छोड़ा गया। super के उपयोग को हटाएं और यह True प्रिंट करता है।

class X(object): 
    def __init__(self): 
     super().__init__() 

    @property 
    def __class__(self): 
     return int 

print (isinstance(X(), int)) 

(ध्यान दें कि यह कोड new super() उपयोग करता है।)

पैच की कार्यक्षमता भी बग रिपोर्ट से के बारे में:

class C(A, B, metaclass=meta): 
    def f(self): 
     return __class__ 

इस तरह लगभग संकलित किया जा करने के लिए::

पैच मूल रूप से निम्नलिखित वर्ग बयान का कारण बनता है

def _outer_C(*__args__, **__kw__): 
    class _inner_C(*__args__, **__kw__): 
     def f(self): 
      return __class__ 
    __class__ = _inner_C 
    return _inner_C 
C = _outer_C(A, B, metaclass=meta) 

... हालांकि कुछ बाद के चर्चा से पता चलता है कि अंतिम पैच में __args__ और __kw__ का संचालन बदल सकता है।

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