मैं पायथन में पायथन कोड युक्त स्ट्रिंग को कैसे निष्पादित करूं?
मैं पायथन में पायथन कोड युक्त स्ट्रिंग को कैसे निष्पादित करूं?
जवाबों:
बयानों के लिए, exec(string)
(पायथन 2/3) या exec string
(पायथन 2) का उपयोग करें:
>>> mycode = 'print "hello world"'
>>> exec(mycode)
Hello world
जब आपको अभिव्यक्ति के मूल्य की आवश्यकता हो, तो उपयोग करें eval(string)
:
>>> x = eval("2+2")
>>> x
4
हालांकि, पहला कदम खुद से पूछना चाहिए कि क्या आपको वास्तव में जरूरत है। निष्पादन कोड आम तौर पर अंतिम उपाय की स्थिति होना चाहिए: यदि यह उपयोगकर्ता-दर्ज कोड हो सकता है, तो यह धीमा, बदसूरत और खतरनाक है। आपको हमेशा पहले विकल्पों को देखना चाहिए, जैसे कि उच्च क्रम वाले कार्य, यह देखने के लिए कि क्या ये आपकी आवश्यकताओं को बेहतर तरीके से पूरा कर सकते हैं।
if s=='foo': x.foo = 42 elif s=='bar': x.bar = 42
आदि कुछ ऐसा है , जिसे वे तब लिख सकते हैं exec ("x.%s = 42" % s)
। इस सामान्य मामले के लिए (जहां आपको केवल किसी ऑब्जेक्ट की विशेषता को एक्सेस करने की आवश्यकता होती है जो एक स्ट्रिंग में संग्रहीत होती है), बहुत तेज़, क्लीनर और सुरक्षित फ़ंक्शन है getattr
: बस getattr(x, s) = 42
एक ही चीज़ का मतलब लिखने के लिए लिखें ।
setattr(x, s, 42)
? मैंने कोशिश की getattr(x, 2) = 42
और इसके साथ असफल रहाcan't assign to function call: <string>, line 1
setattr(x, s, 42)
में सही वाक्यविन्यास है। हैरानी की बात यह है कि उस त्रुटि को पकड़ने में इतनी देर लगी। वैसे भी, मुद्दा यह है कि getattr
और setattr
एक विकल्प है exec
जब आप चाहते हैं कि एक मनमाना सदस्य प्राप्त करना है, स्ट्रिंग द्वारा देखा गया।
उदाहरण में एक स्ट्रिंग को निष्पादन फ़ंक्शन का उपयोग करके कोड के रूप में निष्पादित किया जाता है।
import sys
import StringIO
# create file-like string to capture output
codeOut = StringIO.StringIO()
codeErr = StringIO.StringIO()
code = """
def f(x):
x = x + 1
return x
print 'This is my output.'
"""
# capture output and errors
sys.stdout = codeOut
sys.stderr = codeErr
exec code
# restore stdout and stderr
sys.stdout = sys.__stdout__
sys.stderr = sys.__stderr__
print f(4)
s = codeErr.getvalue()
print "error:\n%s\n" % s
s = codeOut.getvalue()
print "output:\n%s" % s
codeOut.close()
codeErr.close()
exec
से संबंधित होना चाहिए (जब तक आपको पता न हो कि कोड स्ट्रिंग किसी विश्वसनीय स्रोत से आता है)।
eval
और exec
सही समाधान हैं, और उनका उपयोग सुरक्षित रूप से किया जा सकता है तरीके से है।
जैसा कि पायथन के संदर्भ मैनुअल में चर्चा की गई है और इस ट्यूटोरियल में स्पष्ट रूप से समझाया गया है , eval
औरexec
फ़ंक्शन दो अतिरिक्त पैरामीटर लेते हैं जो उपयोगकर्ता को यह निर्दिष्ट करने की अनुमति देते हैं कि वैश्विक और स्थानीय फ़ंक्शन और चर उपलब्ध हैं।
उदाहरण के लिए:
public_variable = 10
private_variable = 2
def public_function():
return "public information"
def private_function():
return "super sensitive information"
# make a list of safe functions
safe_list = ['public_variable', 'public_function']
safe_dict = dict([ (k, locals().get(k, None)) for k in safe_list ])
# add any needed builtins back in
safe_dict['len'] = len
>>> eval("public_variable+2", {"__builtins__" : None }, safe_dict)
12
>>> eval("private_variable+2", {"__builtins__" : None }, safe_dict)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 1, in <module>
NameError: name 'private_variable' is not defined
>>> exec("print \"'%s' has %i characters\" % (public_function(), len(public_function()))", {"__builtins__" : None}, safe_dict)
'public information' has 18 characters
>>> exec("print \"'%s' has %i characters\" % (private_function(), len(private_function()))", {"__builtins__" : None}, safe_dict)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 1, in <module>
NameError: name 'private_function' is not defined
संक्षेप में आप उन नामों को परिभाषित कर रहे हैं जिनमें कोड निष्पादित किया जाएगा।
eval
या exec
इसका उपयोग करने का इरादा है exec(input("Type what you want"))
? ऐसे कई मामले हैं जहां एक कार्यक्रम एक संगणना के परिणामस्वरूप एक प्रक्रिया या कार्य लिख सकता है; परिणामी फ़ंक्शंस एक अच्छे और अच्छी तरह से लिखे गए प्रोग्राम के किसी भी अन्य भाग के रूप में सुरक्षित और तेज़ (एक बार मूल्यांकन किए जाने वाले) होंगे। एक असुरक्षित कार्यक्रम युक्त एक असुरक्षित कार्यक्रम exec
से अधिक खतरनाक नहीं है जो खुद को नुकसान पहुंचाता है क्योंकि exec
यह कार्यक्रम को कोई नया विशेषाधिकार नहीं देता है।
exec
औरeval
exec
औरeval
पाइथन का उस पर अत्यधिक प्रभाव पड़ता है।शीर्ष उत्तर (जोर मेरा) से:
बयानों के लिए, का उपयोग करें
exec
।जब आपको अभिव्यक्ति के मूल्य की आवश्यकता हो, तो उपयोग करें
eval
।हालांकि, पहला कदम खुद से पूछना चाहिए कि क्या आपको वास्तव में जरूरत है। निष्पादन कोड आम तौर पर अंतिम उपाय की स्थिति होना चाहिए : यदि यह उपयोगकर्ता-दर्ज कोड हो सकता है, तो यह धीमा, बदसूरत और खतरनाक है। आपको हमेशा पहले विकल्पों को देखना चाहिए , जैसे कि उच्च क्रम वाले कार्य , यह देखने के लिए कि क्या ये आपकी आवश्यकताओं को बेहतर तरीके से पूरा कर सकते हैं।
से वैकल्पिक करने के लिए कार्यकारी / eval?
स्ट्रिंग्स में नामों के साथ वेरिएबल्स का मान सेट करें और प्राप्त करें
[जबकि
eval
] काम करेगा, यह आमतौर पर चर नाम का उपयोग करने की सलाह नहीं दी जाती है जो प्रोग्राम के लिए एक अर्थ है।इसके बजाय, एक तानाशाही का बेहतर इस्तेमाल करें।
से http://lucumr.pocoo.org/2011/2/1/exec-in-python/ (जोर मेरा)
पायथन PHP नहीं है
पायथन मुहावरों को दरकिनार करने की कोशिश न करें क्योंकि कुछ अन्य भाषा इसे अलग तरह से करती है। नामस्थान एक कारण के लिए पायथन में हैं और सिर्फ इसलिए कि यह आपको उपकरण देता है
exec
इसका मतलब यह नहीं है कि आपको उस उपकरण का उपयोग करना चाहिए।
से http://nedbatchelder.com/blog/201206/eval_really_is_dangerous.html (जोर मेरा)
तो eval सुरक्षित नहीं है, भले ही आप सभी globals और buildins को हटा दें!
इन सभी के निष्कासन () की सुरक्षा के प्रयासों के साथ समस्या यह है कि वे अश्वेत हैं । वे स्पष्ट रूप से उन चीजों को हटाते हैं जो खतरनाक हो सकते हैं। यह एक हारी हुई लड़ाई है क्योंकि अगर सूची से सिर्फ एक आइटम बचा है, तो आप सिस्टम पर हमला कर सकते हैं ।
तो क्या eval को सुरक्षित बनाया जा सकता है? बताना कठिन है। इस बिंदु पर, मेरा सबसे अच्छा अनुमान है कि यदि आप किसी भी डबल अंडरस्कोर का उपयोग नहीं कर सकते हैं, तो आप कोई नुकसान नहीं कर सकते हैं, इसलिए हो सकता है कि यदि आप डबल अंडरस्कोर के साथ किसी भी स्ट्रिंग को बाहर कर दें तो आप सुरक्षित हैं। शायद...
से http://stupidpythonideas.blogspot.it/2013/05/why-evalexec-is-bad.html (जोर मेरा):
सबसे पहले,
exec
यह आपके कोड को पढ़ने के लिए मनुष्य के लिए कठिन बनाता है । क्या हो रहा है, यह जानने के लिए, मुझे आपका कोड नहीं पढ़ना है, मुझे आपका कोड पढ़ना है, यह पता लगाना है कि यह किस स्ट्रिंग को उत्पन्न करने वाला है, फिर उस वर्चुअल कोड को पढ़ें। इसलिए, यदि आप एक टीम पर काम कर रहे हैं, या ओपन सोर्स सॉफ्टवेयर प्रकाशित कर रहे हैं, या स्टैकऑवरफ्लो जैसी कहीं मदद मांग रहे हैं, तो आप अन्य लोगों के लिए आपकी मदद करना कठिन बना रहे हैं। और अगर कोई मौका है कि आप अब से 6 महीने पहले इस कोड पर डिबगिंग या विस्तार करने जा रहे हैं, तो आप इसे सीधे अपने लिए कठिन बना रहे हैं।
cfg.yaml
): reldir : ../my/dir/
और से एक सापेक्ष पथ आयात करना होगा reldir = cfg[reldir]
। हालाँकि, यह अजगर कोड विंडोज और लिनक्स दोनों पर चलेगा, मुझे अलग-अलग ऑपरेटिंग सिस्टम पथ डिवाइडर में समायोजित करने के लिए इसकी आवश्यकता है; भी\\
या /
। इसलिए मैं reldir : os.path.join('..','my','dir')
config फाइल में उपयोग करता हूं । लेकिन इससे केवल reldir
इस शाब्दिक स्ट्रिंग का मूल्यांकन किया जा रहा है, इसलिए मैं एक फ़ाइल नहीं खोल सकता reldir
। आपका कोई सुझाव है?
जैसा कि दूसरों ने उल्लेख किया है, यह "निष्पादित" है।
लेकिन, यदि आपके कोड में वैरिएबल हैं, तो आप इसे एक्सेस करने के लिए "ग्लोबल" का उपयोग कर सकते हैं, साथ ही कंपाइलर को रोकने के लिए निम्नलिखित त्रुटि उठा सकते हैं:
NameError: नाम 'p_variable' परिभाषित नहीं है
exec('p_variable = [1,2,3,4]')
global p_variable
print(p_variable)
यह ध्यान देने योग्य बात है, कि exec
भाई मौजूद है execfile
अगर आप एक अजगर फ़ाइल को कॉल करना चाहते हैं। यह कभी-कभी अच्छा होता है यदि आप किसी तीसरे पक्ष के पैकेज में काम कर रहे हैं जिसमें भयानक आईडीई शामिल है और आप उनके पैकेज के बाहर कोड करना चाहते हैं।
उदाहरण:
execfile('/path/to/source.py)'
या:
exec(open("/path/to/source.py").read())
ठीक है .. मुझे पता है कि यह वास्तव में एक जवाब नहीं है, लेकिन संभवतः लोगों के लिए एक नोट है जो मैं था। मैं विभिन्न उपयोगकर्ताओं / ग्राहकों के लिए विशिष्ट कोड निष्पादित करना चाहता था, लेकिन निष्पादन / निष्कासन से भी बचना चाहता था। मैंने शुरू में प्रत्येक उपयोगकर्ता के लिए एक डेटाबेस में कोड संग्रहीत करने और ऊपर करने के लिए देखा।
मैंने एक 'customer_filters' फोल्डर के भीतर फाइल सिस्टम पर फाइल बनाना और 'imp' मॉड्यूल का उपयोग करना समाप्त कर दिया है, अगर कोई फ़िल्टर उस ग्राहक के लिए लागू नहीं होता है, तो यह सिर्फ चालू रहता है
import imp
def get_customer_module(customerName='default', name='filter'):
lm = None
try:
module_name = customerName+"_"+name;
m = imp.find_module(module_name, ['customer_filters'])
lm = imp.load_module(module_name, m[0], m[1], m[2])
except:
''
#ignore, if no module is found,
return lm
m = get_customer_module(customerName, "filter")
if m is not None:
m.apply_address_filter(myobj)
इसलिए customerName = "jj" ग्राहक_फिल्टर \ jj_filter.py फ़ाइल से apply_address_filter निष्पादित करेगा