ग्लोबल्स के रूप में चर या पाइथन के फ़ंक्शन के स्थानीय लोगों के रूप में eval() पर भिन्नता क्यों होती है?पाइथन के eval() का उपयोग करते समय स्थानीय और ग्लोबल्स के बीच क्या अंतर है?
described in the documenation के साथ, पायथन __builtins__
को ग्लोबल्स में कॉपी करेगा, अगर स्पष्ट रूप से नहीं दिया गया है। लेकिन कुछ और अंतर भी होना चाहिए जो मैं नहीं देख सकता।
निम्न उदाहरण फ़ंक्शन पर विचार करें। यह एक स्ट्रिंग code
लेता है और फ़ंक्शन ऑब्जेक्ट देता है। बिल्टिन की अनुमति नहीं है (उदा। abs()
), लेकिन math
पैकेज से सभी फ़ंक्शन।
def make_fn(code):
import math
ALLOWED_LOCALS = {v:getattr(math, v)
for v in filter(lambda x: not x.startswith('_'), dir(math))
}
return eval('lambda x: %s' % code, {'__builtins__': None}, ALLOWED_LOCALS)
यह काम करता है के रूप में किसी भी स्थानीय या वैश्विक वस्तुओं का उपयोग नहीं की उम्मीद:
fn = make_fn('x + 3')
fn(5) # outputs 8
लेकिन यह math
कार्यों का उपयोग कर काम नहीं करता:
fn = make_fn('cos(x)')
fn(5)
यह निम्नलिखित अपवाद आउटपुट:
<string> in <lambda>(x)
NameError: global name 'cos' is not defined
लेकिन जब वैश्विक रूप में एक ही मानचित्रण गुजर यह काम करता है:
def make_fn(code):
import math
ALLOWED = {v:getattr(math, v)
for v in filter(lambda x: not x.startswith('_'), dir(math))
}
ALLOWED['__builtins__'] = None
return eval('lambda x: %s' % code, ALLOWED, {})
एक ही रूप में ऊपर के उदाहरण:
fn = make_fn('cos(x)')
fn(5) # outputs 0.28366218546322625
क्या विस्तार से यहाँ क्या होता है?
प्रलेखन में यह कहा जाता है कि "ग्लोबल्स शब्दकोश मौजूद है और '__builtins__' की कमी है। मुझे लगता है कि इसका मतलब यह है कि कुंजी '__builtins__' मौजूद नहीं है, लेकिन आपके उदाहरण में, आप इसे किसी भी पर सेट नहीं करते हैं। मेरा सुझाव है कि आपको अनुमति दी जानी चाहिए ['__ बनाया गया'] = किसी भी डेल द्वारा दिए गए ['__ बनाया गया'] और इसे फिर से प्रयास करें। – jorispilot
@jorispilot मेरा मुद्दा __builtins__ से जुड़ा नहीं है। मैंने अभी इसका उल्लेख किया है, क्योंकि eval द्वारा globals के इस विशेष आवरण है। जिस तरह से मैंने __builtins__ को सेट नहीं किया है, वह सही है, अगर आप 'abs' जैसे बिल्टिन फ़ंक्शंस को मना करना चाहते हैं। 'cos' एक निर्मित फ़ंक्शन नहीं है, यह 'गणित' मॉड्यूल का हिस्सा है। – lumbric