2017-11-24 23 views
7

मैं आज पाइथन स्कोप का अध्ययन कर रहा हूं और कुछ प्रयोग किए हैं। और मुझे एक दिलचस्प घटना मिली। आयातित फ़ंक्शन के अंदर exec("global var; var = value") पर कॉल करके। मैं इस मूल्य को कहीं अज्ञात में स्टोर कर सकता हूं। और बाद में मैं import module; print(module.var) का उपयोग करके इसे पुनर्प्राप्त कर सकता हूं।() से पहले और str_to_global_var समारोह (deepcopy असफल हो जायेगी) उपयोग करने के बादपाइथन एक आयातित फ़ंक्शन के वैश्विक स्कोप चर कहां स्टोर करता है?

# temp.py 
def str_to_global_var(string, obj): 
    command_1 = 'global %s; %s=%r' % (string, string, obj) 
    exec(command_1) 



# script.py 
from copy import copy 
from temp import str_to_global_var 

cur_global = copy(globals()) 
str_to_global_var('x', 6) 

new_global = globals() 

print(set(new_global.keys()) - set(cur_global.keys())) 

d2 = copy(new_global) 
d1 = copy(cur_global) 

del d2['cur_global'] 
del d2['new_global'] 

print('Compare d2==d1: ', d2 == d1) 
print("'x' in new_global: ",'x' in new_global) 

import temp 
print("temp.x:", temp.x) 



# Interpreter running result 
>>> ipython3 script.py 

{'new_global', 'cur_global'} 
Compare d2==d1: True 
'x' in new_global: False 
temp.x: 6 

मैं script.py के वैश्विक का एक उथले प्रतिलिपि किया था: कृपया कोड नीचे देखें। वे 2 अप्रासंगिक पहचानकर्ता "new_global" और "cur_global" को हटाने के बराबर तुलना कर रहे हैं, इसलिए यह उथले प्रतिलिपि स्तर पर कहा जाता है, दुभाषिया ने सोचा कि आयातित str_to_global_var फ़ंक्शन का उपयोग करने के बाद script.py के वैश्विक दायरे में कुछ भी नहीं बदला है, क्योंकि हम सभी इसे जानते हैं केवल temp.py के दायरे में एक वैश्विक चर अद्यतन करता है।

लेकिन सवाल यह है कि, हम import temp.py; print(temp.var) कथन का उपयोग करने से पहले।
पाइथन ने इस temp.var के मूल्य को कहाँ संग्रहीत किया?
मैं इसे कैसे एक्सेस कर सकता हूं?
और यदि मैं script.py के लिए ग्लोबल्स अपडेट करने के लिए आयातित str_to_global_var फ़ंक्शन बनाना चाहता हूं, तो क्या इसकी विशेषता को संशोधित करने के लिए कोई चाल है ताकि python इसे script.py के फ़ंक्शन के रूप में पहचाना जा सके?

उत्तर

7

यहाँ कि sys का उपयोग कर बुला मॉड्यूल पर काम करता है str_to_global का एक उदाहरण है।_getframe:

#a.py 
def str_to_global(name, value): 
    sys._getframe(1).f_globals[name] = value 

#b.py 
from a import str_to_global 
str_to_global('cheese', 'cake') 
print(cheese) 

केक

3

अपने कोड

str_to_global_var('x', 6) 

वैश्विक चर मॉड्यूल अस्थायी में बनाया जाता है फोन करके

def str_to_global_var(string, obj): 
    command_1 = 'global %s; %s=%r' % (string, string, obj) 
    exec(command_1) 

निष्पादित दी जाती है। आपको लगता है कि पुष्टि कर सकते हैं नीचे

print ('x' in str_to_global_var.__globals__) 
print (str_to_global_var.__globals__['x']) 

का उपयोग करके उत्पादन किया जाएगा

True 
6 

डिफ़ॉल्ट रूप से आप एक और मॉड्यूल से वर्तमान मॉड्यूल के संदर्भ संशोधित नहीं कर सकते। तो अगर आप कोड

x = 10 
str_to_global_var('x', 6) 
print ("x = " + str(x)) 

नीचे है, तो आप वर्तमान मॉड्यूल संदर्भ में चर को संशोधित करना चाहते हैं उत्पादन

x = 10 

हो जाएगा तो आप समारोह

def str_to_global_var2(globalsvar, string, obj): 
    command_1 = 'globalsvar["%s"] = %r' % (string, obj) 
    exec(command_1) 
को भी इस संदर्भ में उत्तीर्ण होना

और फिर इसे

x = 10 
str_to_global_var2(globals(), 'x', 6) 
print ("x = " + str(x)) 
से नीचे कॉल करें

व्यवहृत किया जा सकेगा

x = 6 

समारोह के रूप में सरल किया जा सकता

def str_to_global_var3(globalsvar, string, obj): 
    globalsvar[string] = obj 
+0

धन्यवाद। प्रश्न में अभी भी एक संदेह है। क्या इंटरैक्टिव प्रॉम्प्ट में कुछ विशेष विशेषताओं को संशोधित करके, कुछ प्रकार की चाल मुझे script.py के एक स्ट्रिंग को 'str_to_global_var' बनाने में मदद कर सकती है? – Zen

+0

वैसे, आपके नए लिखित फ़ंक्शन 'str_to_global_var2' में एक बग है। जिसमें 'command_1''% r [% s] =% r "% (global_vars, string, obj)' 'globalsvar ["% s"] =% r'% (स्ट्रिंग, obj) के बजाय होना चाहिए ' – Zen

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