2015-01-28 4 views
5

पायथन कंपाइलर द्वारा उत्पन्न एक कोड ऑब्जेक्ट में निर्देशों (co_consts नामित) में उपयोग किए गए स्थिरांक का एक टुपल होता है और इसमें एक टुपल नाम होते हैं (नाम co_names)।python VM में co_consts का उपयोग करने के बजाय co_names क्यों हैं?

दो अलग-अलग सूचियां क्यों हैं? नामों के लिए co_consts का उपयोग करने के लिए आसान नहीं होगा?

+0

बस जांचने के लिए, आप cpython के बारे में सही बात कर रहे हैं? कौन सा संस्करण? –

+0

@GamesBrainiac: 'co_names' cpython दोनों 2 और 3 और pypy में प्रयोग किया जाता है। अन्य कार्यान्वयन के बारे में निश्चित नहीं है क्योंकि मैं उनका उपयोग नहीं करता हूं। – 6502

+0

मुझे यह सब ठीक नहीं याद है, लेकिन मुझे पूरा यकीन है कि इसमें पिकलिंग के साथ कुछ करना है। –

उत्तर

6

निम्नलिखित फ़ंक्शन पर विचार करें।

def f(x): 
    x += n 
    return x * 4 

यहां x एक स्थानीय नाम है, इसका मूल्य बदल सकता है। 4 एक स्थिर है। इसका मूल्य कभी नहीं बदलेगा। हालांकि, यह अभी भी एक वस्तु है और हर बार इसकी आवश्यकता होने पर एक नई वस्तु बनाने के बजाय उन्हें कैश करना बेहतर होता है। अंत में, n एक वैश्विक संदर्भ है। स्ट्रिंग "n" फ़ंक्शन द्वारा संग्रहीत है ताकि इसे फ़ंक्शन के वैश्विक संदर्भ से n पुनर्प्राप्त करने के लिए कुंजी के रूप में उपयोग किया जा सके।

>>> f.__code__.co_nlocals # just 1 (for x) 
1 
>>> f.__code__.co_consts 
(None, 4) 
>>> f.__code__.co_names 
('n',) 
>>> "n" in f.__globals__ and globals() is f.__globals__ 
True 

आत्मनिरीक्षण के प्रयोजनों के लिए नाम रखने और अलग करने का कारण अलग है। Tuples मर्ज करने का एकमात्र असली कारण स्मृति दक्षता होगी, हालांकि यह केवल आपको एक वस्तु और एक सूचक प्रति समारोह प्राप्त करेगा। निम्नलिखित कार्य पर विचार करें।

def g(): 
    return "s" * n 

तो consts युक्त टपल टपल युक्त नाम के साथ विलय कर दिया गया है तो आप (नहीं वीएम) बताने के लिए जो मान तक पहुँचने वैश्विक लिए थे और जो समारोह के स्थिरांक थे में सक्षम नहीं होगा।

1

मैं जानता हूँ कि क्या यह उत्तर 11 महीनों की तरह है पुराना हो चुका है लेकिन मेरे फेरबदल से ऐसा लगता है निम्नलिखित

हो रहा है बाईटकोड में co_names पहुंचने के लिए, एक LOAD_GLOBAL (सह नाम सूचकांक) का उपयोग करता है और इस के लिए एक संदर्भ धक्का ढेर पर वांछित co_names, जैसे अपने

बाईटकोड में co_consts उपयोग करने के लिए अप्रत्यक्ष, एक LOAD_CONST (सह consts सूचकांक) का उपयोग करता है और इस ढेर इसके प्रत्यक्ष

मैं, जैसे पर वांछित co_consts पर संग्रहीत वास्तविक मूल्य को धक्का मुझे यकीन नहीं है कि इसका पाइथन स्तर पर कोई प्रत्यक्ष असर है, लेकिन बाइटकोड स्तर पर यह एक profou है nd अंतर

+0

बेशक वहाँ एक बड़ा अंतर है क्योंकि 'LOAD_CONST' स्टैक पर निरंतर लोड होता है जबकि' LOAD_GLOBAL' इसके बजाय एक लुकअप करता है। हालांकि वैश्विक ** नाम ** सिर्फ एक पायथन 'str' ऑब्जेक्ट है और' co_names' की बजाय 'co_consts' सूची में रखा जा सकता था। मेरे प्रश्न का मुद्दा यह है कि "केवल co coconcon' का उपयोग करते समय दो सूचियों का उपयोग क्यों किया जा सकता था?" ... मैं ** ** नहीं कह रहा हूं कि 'LOAD_GLOBAL' ऑपोड की आवश्यकता नहीं है क्योंकि हमारे पास 'LOAD_CONST' है , लेकिन सिर्फ दो ही दो सूचियों के बजाय एक ही सूची का इस्तेमाल कर सकते थे। ** नाम ** का जिक्र करने वाला कोई भी ऑपोड 'op_consts' का उपयोग कर सकता था। – 6502

+0

मुझे इस तरह के डिजाइन के कारण पता नहीं है लेकिन 2 प्रशिक्षकों ने विभिन्न प्रकार के डेटा को स्टैक (मूल्य बनाम संदर्भ) –

+0

पर धक्का दिया है यदि आपके पास दोनों कॉन्स और नाम विलय हो गए हैं तो आपको अभी भी कुछ प्रकार के निर्देशों की आवश्यकता होगी वीएम चाहे वह एक संदर्भ या मूल्य हो, ताकि प्रति लोड 2 निर्देश हों, जैसे loadconstname, setconstnametype, और यह एक कॉल के रूप में तेज़ नहीं है, और यदि आपके पास idteuts (उदाहरण के लिए) है जो बाइटकोड के साथ गड़बड़ कर रहा है तो यह VM से सुरक्षित है परिप्रेक्ष्य –

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

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