Python Language
`Exec` और` eval` के साथ डायनामिक कोड का निष्पादन
खोज…
वाक्य - विन्यास
- eval (अभिव्यक्ति [, ग्लोबल्स = कोई नहीं [, स्थानीय = कोई नहीं]])
- कार्यकारी (वस्तु)
- निष्पादन (ऑब्जेक्ट, ग्लोबल्स)
- निष्पादन (ऑब्जेक्ट, ग्लोबल्स, लोकल)
पैरामीटर
बहस | विवरण |
---|---|
expression | एक स्ट्रिंग के रूप में अभिव्यक्ति कोड, या एक code ऑब्जेक्ट |
object | एक स्ट्रिंग के रूप में बयान कोड, या एक code ऑब्जेक्ट |
globals | वैश्विक चर के लिए उपयोग करने का शब्दकोश। यदि स्थानीय निर्दिष्ट नहीं है, तो इसका उपयोग स्थानीय लोगों के लिए भी किया जाता है। यदि छोड़ा गया है, तो कॉलिंग स्कोप के globals() का उपयोग किया जाता है। |
locals | एक मैपिंग ऑब्जेक्ट जिसका उपयोग स्थानीय चर के लिए किया जाता है। यदि छोड़ दिया जाता है, तो globals लिए पारित एक का उपयोग किया जाता है। यदि दोनों को छोड़ दिया जाता है, तो कॉलिंग स्कोप के globals() और locals() को क्रमशः globals और locals लिए उपयोग किया जाता है। |
टिप्पणियों
exec
, यदि globals
locals
(अर्थात वे उसी वस्तु को संदर्भित करते हैं), तो कोड निष्पादित किया जाता है जैसे कि यह मॉड्यूल स्तर पर है। यदि globals
और locals
अलग-अलग ऑब्जेक्ट हैं, तो कोड को निष्पादित किया जाता है जैसे कि यह एक क्लास बॉडी में था ।
यदि globals
वस्तु में पारित हो जाता है, लेकिन निर्दिष्ट नहीं करता __builtins__
कुंजी है, तो अजगर बिल्ट-इन कार्य और नाम स्वचालित रूप से वैश्विक क्षेत्र में जुड़ जाते हैं। इस तरह के रूप में भी कार्य की उपलब्धता को दबाने के लिए print
या isinstance
निष्पादित दायरे में, चलो globals
कुंजी है __builtins__
मान पर मैप None
। हालाँकि, यह एक सुरक्षा सुविधा नहीं है।
पायथन 2-विशिष्ट सिंटैक्स का उपयोग नहीं किया जाना चाहिए; पायथन 3 सिंटैक्स पायथन 2 में काम करेगा। इस प्रकार निम्नलिखित रूपों को पदावनत किया गया है: <s>
-
exec object
-
exec object in globals
-
exec object in globals, locals
निष्पादन के साथ बयानों का मूल्यांकन
>>> code = """for i in range(5):\n print('Hello world!')"""
>>> exec(code)
Hello world!
Hello world!
Hello world!
Hello world!
Hello world!
Eval के साथ एक अभिव्यक्ति का मूल्यांकन
>>> expression = '5 + 3 * a'
>>> a = 5
>>> result = eval(expression)
>>> result
20
कई बार इसका मूल्यांकन करने के लिए एक अभिव्यक्ति को प्राथमिकता देना
compile
बिल्ट-इन फ़ंक्शन का उपयोग किसी कोड ऑब्जेक्ट के लिए एक अभिव्यक्ति को गति देने के लिए किया जा सकता है; इस कोड ऑब्जेक्ट को फिर से निकाला जा सकता है। यह मूल्यांकन किए गए कोड के बार-बार निष्पादन को गति देगा। compile
करने के लिए 3 पैरामीटर को स्ट्रिंग 'eval'
होना चाहिए।
>>> code = compile('a * b + c', '<string>', 'eval')
>>> code
<code object <module> at 0x7f0e51a58830, file "<string>", line 1>
>>> a, b, c = 1, 2, 3
>>> eval(code)
5
कस्टम ग्लोबल्स का उपयोग करके eval के साथ एक अभिव्यक्ति का मूल्यांकन
>>> variables = {'a': 6, 'b': 7}
>>> eval('a * b', globals=variables)
42
प्लस के रूप में, इस कोड के साथ गलती से बाहर परिभाषित नामों का उल्लेख नहीं किया जा सकता है:
>>> eval('variables')
{'a': 6, 'b': 7}
>>> eval('variables', globals=variables)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 1, in <module>
NameError: name 'variables' is not defined
defaultdict
का उपयोग करना उदाहरण के लिए अपरिभाषित चर को शून्य पर सेट करने की अनुमति देता है:
>>> from collections import defaultdict
>>> variables = defaultdict(int, {'a': 42})
>>> eval('a * c', globals=variables) # note that 'c' is not explicitly defined
0
Ast.literal_eval के साथ पायथन शाब्दिक युक्त स्ट्रिंग का मूल्यांकन
यदि आपके पास एक स्ट्रिंग है जिसमें पायथन शाब्दिक शब्द हैं, जैसे कि स्ट्रिंग्स, फ्लोट्स आदि, तो आप eval
बजाय इसके मूल्य का मूल्यांकन करने के लिए ast.literal_eval
का उपयोग कर सकते हैं। इसमें केवल कुछ सिंटैक्स की अनुमति देने की अतिरिक्त सुविधा है।
>>> import ast
>>> code = """(1, 2, {'foo': 'bar'})"""
>>> object = ast.literal_eval(code)
>>> object
(1, 2, {'foo': 'bar'})
>>> type(object)
<class 'tuple'>
हालांकि, यह अविश्वसनीय उपयोगकर्ता द्वारा प्रदान किए गए कोड के निष्पादन के लिए सुरक्षित नहीं है, और सावधानीपूर्वक इनपुट इनपुट के साथ दुभाषिया को दुर्घटनाग्रस्त करने के लिए तुच्छ है
>>> import ast
>>> ast.literal_eval('()' * 1000000)
[5] 21358 segmentation fault (core dumped) python3
यहाँ, इनपुट एक स्ट्रिंग है ()
एक मिलियन बार दोहराया गया, जो सीपीथॉन पार्सर में दुर्घटना का कारण बनता है। CPython Developers पार्सर में बग को सुरक्षा मुद्दों के रूप में नहीं मानते हैं।
निष्पादन, निष्कासन, या ast.literal_eval का उपयोग करके अविश्वासित उपयोगकर्ता द्वारा प्रदान किया गया निष्पादन कोड
यह उपयोग करने के लिए संभव नहीं है eval
या exec
सुरक्षित रूप से अविश्वसनीय उपयोगकर्ता से कोड निष्पादित करने के लिए। यहां तक कि ast.literal_eval
को पार्सर में दुर्घटनाग्रस्त होने का खतरा है। कभी-कभी दुर्भावनापूर्ण कोड निष्पादन के खिलाफ गार्ड करना संभव होता है, लेकिन यह पार्सर या टोकन में एकमुश्त क्रैश की संभावना को बाहर नहीं करता है।
एक अविश्वसनीय उपयोगकर्ता द्वारा कोड का मूल्यांकन करने के लिए आपको कुछ तृतीय-पक्ष मॉड्यूल की ओर मुड़ना होगा, या शायद अपने खुद के पार्सर और अपनी खुद की वर्चुअल मशीन को पायथन में लिखना होगा।