जिस किताब में मैं पायथन पर पढ़ रहा हूं, वह कोड का उपयोग करता रहता है eval(input('blah'))
मैं प्रलेखन पढ़ता हूं, और मैं इसे समझता हूं, लेकिन मैं अभी भी यह नहीं देखता कि यह input()
फ़ंक्शन कैसे बदलता है ।
यह क्या करता है? क्या कोई समझा सकता है?
जिस किताब में मैं पायथन पर पढ़ रहा हूं, वह कोड का उपयोग करता रहता है eval(input('blah'))
मैं प्रलेखन पढ़ता हूं, और मैं इसे समझता हूं, लेकिन मैं अभी भी यह नहीं देखता कि यह input()
फ़ंक्शन कैसे बदलता है ।
यह क्या करता है? क्या कोई समझा सकता है?
जवाबों:
निष्कासन कार्य एक पायथन प्रोग्राम को अपने भीतर पायथन कोड चलाने की सुविधा देता है।
eval उदाहरण (इंटरेक्टिव शेल):
>>> x = 1
>>> eval('x + 1')
2
>>> eval('x')
1
eval()
अत्यधिक-गतिशील कोड को निष्पादित करने के लिए भी इस्तेमाल किया जा सकता है, लेकिन आपको इसका उपयोग करने से पहले सुरक्षा और प्रदर्शन जोखिमों से खुद को पूरी तरह से अवगत कराना चाहिए।
eval
, और न ही यह इसके साथ क्या कर सकता है eval
।
eval
, असुरक्षित होने के अलावा, कोडपैड जैसे पूरे कार्यक्रम नहीं चला सकते क्योंकि यह केवल एक अभिव्यक्ति का मूल्यांकन कर सकता है।
eval()
कोड के रूप में एक स्ट्रिंग की व्याख्या करता है। इसका उपयोग करने के बारे में आपको इतने लोगों ने चेतावनी दी है, इसका कारण यह है कि एक उपयोगकर्ता इसे कंप्यूटर पर कोड चलाने के लिए एक विकल्प के रूप में उपयोग कर सकता है। यदि आपके पास है eval(input())
और os
आयात किया गया है, तो एक व्यक्ति टाइप कर सकता है, input()
os.system('rm -R *')
जो आपकी सभी फाइलों को आपके होम डायरेक्टरी में हटा देगा। (मान लें कि आपके पास एक यूनिक्स प्रणाली है)। उपयोग करना eval()
एक सुरक्षा छेद है। यदि आपको स्ट्रिंग्स को अन्य प्रारूपों में बदलने की आवश्यकता है, तो उन चीजों का उपयोग करने का प्रयास करें जो ऐसा करते हैं, जैसे int()
।
eval
के साथ input()
एक सुरक्षा छेद है। input()
एक स्पष्ट विवरण के अंदर मत डालो और तुम ठीक हो जाओगे।
eval
कई मामलों में एक सुरक्षा मुद्दा है।
input
आमतौर पर कंसोल से इसका डेटा उपयोगकर्ता लेता है, इसलिए उपयोगकर्ता प्रोग्राम से बाहर निकल सकता है और rm -R *
वैसे भी टाइप कर सकता है ...
यहाँ बहुत सारे अच्छे उत्तर हैं, लेकिन eval()
इसके globals
और locals
कवारों के संदर्भ में उपयोग का कोई भी वर्णन नहीं करता है , अर्थात eval(expression, globals=None, locals=None)
( eval
यहाँ के लिए डॉक्स देखें )।
इनका उपयोग फ़ंक्शन के माध्यम से उपलब्ध कार्यों को सीमित करने के लिए किया जा सकता है eval
। उदाहरण के लिए यदि आप एक ताजा अजगर इंटरप्रेटर को लोड करते हैं locals()
और globals()
वह समान होगा और कुछ इस तरह दिखेगा:
>>>globals()
{'__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__doc__': None,
'__spec__': None, '__builtins__': <module 'builtins' (built-in)>,
'__package__': None, '__name__': '__main__'}
builtins
मॉड्यूल के भीतर निश्चित रूप से कार्य हैं जो एक सिस्टम को महत्वपूर्ण नुकसान पहुंचा सकते हैं। लेकिन कुछ भी और जो कुछ भी हम उपलब्ध नहीं करना चाहते हैं, उसे रोकना संभव है। एक उदाहरण लेते हैं। कहें कि हम सिस्टम पर उपलब्ध कोर के एक डोमेन का प्रतिनिधित्व करने के लिए एक सूची का निर्माण करना चाहते हैं। मेरे लिए मेरे पास 8 कोर हैं इसलिए मुझे एक सूची चाहिए [1, 8]
।
>>>from os import cpu_count
>>>eval('[1, cpu_count()]')
[1, 8]
इसी तरह सभी __builtins__
उपलब्ध है।
>>>eval('abs(-1)')
1
ठीक है। इसलिए, हम एक ऐसा कार्य देखते हैं जिसे हम उजागर करना चाहते हैं और एक का उदाहरण (कई का और अधिक जटिल हो सकता है) विधि जिसे हम उजागर नहीं करना चाहते हैं। तो चलो सब कुछ ब्लॉक।
>>>eval('[1, cpu_count()]', {'__builtins__':None}, {})
TypeError: 'NoneType' object is not subscriptable
हमने प्रभावी रूप से सभी __builtins__
कार्यों को अवरुद्ध कर दिया है और जैसे हमारे सिस्टम में सुरक्षा का स्तर लाया है। इस बिंदु पर हम उन कार्यों में वापस जोड़ना शुरू कर सकते हैं जिन्हें हम उजागर करना चाहते हैं।
>>>from os import cpu_count
>>>exposed_methods = {'cpu_count': cpu_count}
>>>eval('cpu_count()', {'__builtins__':None}, exposed_methods)
8
>>>eval('abs(cpu_count())', {'__builtins__':None}, exposed_methods)
TypeError: 'NoneType' object is not subscriptable
अब हमारे पास वह cpu_count
फ़ंक्शन उपलब्ध है जो अभी भी हम चाहते हैं कि सब कुछ अवरुद्ध कर रहे हैं। मेरी राय में, यह अन्य उत्तरों के दायरे से सुपर शक्तिशाली और स्पष्ट रूप से है, एक सामान्य कार्यान्वयन नहीं है। इस तरह से कुछ के लिए कई उपयोग हैं और जब तक यह सही ढंग से संभाला जाता है मुझे व्यक्तिगत रूप से लगता हैeval
रूप से महान मूल्य के लिए सुरक्षित रूप से उपयोग किया जा सकता है।
एनबी
इनके बारे में कुछ और अच्छा kwargs
है कि आप अपने कोड के लिए शॉर्टहैंड का उपयोग करना शुरू कर सकते हैं। मान लें कि आप कुछ आयातित पाठ को निष्पादित करने के लिए पाइपलाइन के हिस्से के रूप में eval का उपयोग करते हैं। पाठ को सटीक कोड की आवश्यकता नहीं है, यह कुछ टेम्प्लेट फ़ाइल प्रारूप का अनुसरण कर सकता है, और फिर भी कुछ भी निष्पादित कर सकता है जो आप चाहते हैं। उदाहरण के लिए:
>>>from os import cpu_count
>>>eval('[1,cores]', {'__builtins__': None}, {'cores': cpu_count()})
[1, 8]
पायथन में 2.x input(...)
के बराबर है eval(raw_input(...))
, पायथन में 3.x raw_input
का नाम बदल दिया गया था input
, जिस पर मुझे संदेह है कि आपके भ्रम की स्थिति है (आप शायद input
पायथन 2.x में प्रलेखन देख रहे थे )। इसके अतिरिक्त, eval(input(...))
पायथन 3.x में ठीक काम करेगा, लेकिन TypeError
पायथन 2 में एक जुट करेगा ।
इस मामले में एक अभिव्यक्ति से व्याख्या eval
की गई स्ट्रिंग की input
व्याख्या करने और व्याख्या करने के लिए उपयोग किया जाता है । आमतौर पर यह बुरा अभ्यास माना जाता है।
input
जिसका अर्थ है कि raw_input
2.x में क्या किया।
शायद एक पंक्ति को पढ़ने और उसकी व्याख्या करने का एक भ्रामक उदाहरण।
प्रयत्न eval(input())
और टाइप करें "1+1"
- यह प्रिंट होना चाहिए 2
। मूल्यांकन भावों का मूल्यांकन करता है।
eval()
पायथन अभिव्यक्ति के रूप में पारित स्ट्रिंग का मूल्यांकन करता है और परिणाम देता है। उदाहरण के लिए, eval("1 + 1")
अभिव्यक्ति की व्याख्या और निष्पादन करता है"1 + 1"
और परिणाम (2) देता है।
आपके द्वारा भ्रमित किए जाने का एक कारण यह हो सकता है कि आपके द्वारा उद्धृत कोड में अप्रत्यक्ष स्तर शामिल है। आंतरिक फ़ंक्शन कॉल (इनपुट) पहले निष्पादित हो जाती है, इसलिए उपयोगकर्ता "ब्लाह" शीघ्र देखता है। आइए कल्पना करें कि वे "1 + 1" के साथ प्रतिक्रिया करते हैं (उद्धरण आपके स्पष्टता के लिए जोड़ा जाता है, अपने प्रोग्राम को चलाते समय उन्हें टाइप न करें), इनपुट फ़ंक्शन उस स्ट्रिंग को लौटाता है, जिसे बाद में बाहरी फ़ंक्शन (eval) में भेजा जाता है जो स्ट्रिंग की व्याख्या करता है और परिणाम (2) देता है।
Eval बारे में अधिक पढ़ें यहाँ ।
eval()
, जैसा कि नाम से पता चलता है, पारित तर्क का मूल्यांकन करता है।
raw_input()
अब input()
अजगर 3.x संस्करणों में है। तो सबसे अधिक पाया जाने वाला उदाहरण eval()
इसके उपयोग के लिए है जो कार्यक्षमता प्रदान करता है जो कि input()
अजगर के 2.x संस्करण में प्रदान किया गया है। raw_input ने उपयोगकर्ता द्वारा दर्ज किए गए डेटा को एक स्ट्रिंग के रूप में वापस किया, जबकि इनपुट ने दर्ज किए गए डेटा के मूल्य का मूल्यांकन किया और उसे वापस कर दिया।
eval(input("bla bla"))
इस प्रकार input()
, उपयोगकर्ता द्वारा दर्ज किए गए डेटा का मूल्यांकन करने के लिए, 2.x की कार्यक्षमता को दोहराता है ।
संक्षेप में: इसके eval()
लिए पारित तर्कों का मूल्यांकन करता है और इसलिए eval('1 + 1')
2 लौटाता है ।
उनमें से एक उपयोगी अनुप्रयोग eval()
स्ट्रिंग से अजगर के भावों का मूल्यांकन करना है। उदाहरण के लिए फ़ाइल स्ट्रिंग से शब्दकोश का प्रतिनिधित्व:
running_params = {"Greeting":"Hello "}
fout = open("params.dat",'w')
fout.write(repr(running_params))
fout.close()
इसे एक चर के रूप में पढ़ें और इसे संपादित करें:
fin = open("params.dat",'r')
diction=eval(fin.read())
diction["Greeting"]+="world"
fin.close()
print diction
आउटपुट:
{'Greeting': 'Hello world'}
eval
करता है?
मुझे इस प्रश्न का उत्तर देने में देर हो रही है लेकिन, कोई भी इस प्रश्न का स्पष्ट उत्तर नहीं देता है।
यदि कोई उपयोगकर्ता संख्यात्मक मान दर्ज करता है, input()
तो एक स्ट्रिंग लौटाएगा।
>>> input('Enter a number: ')
Enter a number: 3
>>> '3'
>>> input('Enter a number: ')
Enter a number: 1+1
'1+1'
तो, eval()
लौटे मूल्य (या अभिव्यक्ति) का मूल्यांकन करेंगे जो एक स्ट्रिंग और रिटर्न पूर्णांक / फ्लोट है।
>>> eval(input('Enter a number: '))
Enter a number: 1+1
2
>>>
>>> eval(input('Enter a number: '))
Enter a number: 3.14
3.14
यह एक बुरा अभ्यास है। int()
या इस मामले के float()
बजाय इस्तेमाल किया जाना चाहिए eval()
।
>>> float(input('Enter a number: '))
Enter a number: 3.14
3.14
एक अन्य विकल्प यदि आप मूल्यांकन स्ट्रिंग को सरल शाब्दिकता तक सीमित करना चाहते हैं, तो इसका उपयोग करना है ast.literal_eval()
। कुछ उदाहरण:
import ast
# print(ast.literal_eval('')) # SyntaxError: unexpected EOF while parsing
# print(ast.literal_eval('a')) # ValueError: malformed node or string
# print(ast.literal_eval('import os')) # SyntaxError: invalid syntax
# print(ast.literal_eval('1+1')) # 2: but only works due to a quirk in parser
# print(ast.literal_eval('1*1')) # ValueError: malformed node or string
print(ast.literal_eval("{'a':1}")) # {'a':1}
से डॉक्स :
सुरक्षित रूप से एक अभिव्यक्ति नोड या एक पायथन शाब्दिक या कंटेनर डिस्प्ले युक्त स्ट्रिंग का मूल्यांकन करें। प्रदान की गई स्ट्रिंग या नोड केवल हो सकता है निम्नलिखित पायथन शाब्दिक संरचनाएं शामिल : स्ट्रिंग्स, बाइट्स, संख्याएं, ट्यूपल्स, सूचियां, डीकट्स, सेट, बुलियन और कोई नहीं।
इसका उपयोग उन मूल्यों को पार्स करने की आवश्यकता के बिना अविश्वसनीय स्रोतों से पायथन मूल्यों वाले तार का सुरक्षित रूप से मूल्यांकन करने के लिए किया जा सकता है। यह संचालकों या अनुक्रमण को शामिल करने के लिए, मनमाने ढंग से जटिल अभिव्यक्तियों का मूल्यांकन करने में सक्षम नहीं है ।
मेलिंग सूची से यह इतना सीमित क्यों है :
शाब्दिक के साथ संचालक अभिव्यक्ति की अनुमति संभव है, लेकिन वर्तमान कार्यान्वयन की तुलना में बहुत अधिक जटिल है। एक सरल कार्यान्वयन सुरक्षित नहीं है: आप बिना किसी प्रयास के मूल रूप से अनबाउंड सीपीयू और मेमोरी उपयोग को प्रेरित कर सकते हैं ("9 ** 9 ** 9" या "[कोई नहीं] * 9 ** 9")।
उपयोगिता के लिए, यह फ़ंक्शन शाब्दिक मूल्यों और कंटेनरों को "रीड बैक" करने के लिए उपयोगी है जैसा कि repr () द्वारा कड़ा किया गया है। यह उदाहरण के लिए एक प्रारूप में क्रमांकन के लिए उपयोग किया जा सकता है जो कि JSON की तुलना में अधिक शक्तिशाली है।
ast.literal_eval
आपके '1+1'
उदाहरण के विपरीत, ऑपरेटरों का समर्थन नहीं करता है । फिर भी यह सूची, संख्या, तार आदि का समर्थन करता है, और इसलिए यह सामान्य eval
उपयोग के मामलों के लिए एक अच्छा विकल्प है ।