2010-10-16 15 views
6

कोड के लिए से 'प्रिंट' कॉल कर सकते हैं:क्यों मैं 'eval'

#!/usr/bin/python 

src = """ 
print '!!!' 
import os 
""" 

obj = compile(src, '', 'exec') 
eval(obj, {'__builtins__': False}) 

मैं उत्पादन:

!!! 
Traceback (most recent call last): 
    File "./test.py", line 9, in <module> 
    eval(obj, {'__builtins__': False}) 
    File "", line 3, in <module> 

ImportError: __import__ not found 

दोनों 'प्रिंट' और 'आयात' भाषा निर्माण कर रहे हैं। 'Eval' 'आयात' का उपयोग क्यों प्रतिबंधित करता है लेकिन 'प्रिंट' को प्रतिबंधित नहीं करता है?

पीएस मैं पाइथन 2.6

अद्यतन का उपयोग कर रहा हूं: प्रश्न नहीं है "आयात क्यों काम नहीं करता है?" लेकिन "प्रिंट क्यों काम करता है?" क्या कुछ वास्तुकला प्रतिबंध हैं या कुछ और?

उत्तर

6

__import__ विधि import कीवर्ड द्वारा लाया जाता है: python.org

आप एक मॉड्यूल आप की जरूरत आयात करने में सक्षम होना चाहते हैं बिल्टिन में __import__ विधि छोड़ें:

src = """ 
print '!!!' 
import os 
""" 

obj = compile(src, '', 'exec') 
eval(obj, {'__builtins__': {'__import__':__builtins__.__import__}}) 
+0

प्रश्न नहीं है "आयात क्यों काम नहीं करता है?" लेकिन "प्रिंट क्यों काम करता है?" – Tiendil

+0

प्रिंट पायथन 3k में एक विधि बन जाता है, मुझे लगता है कि यह अब और काम नहीं करेगा :) – Sacha

2

अपने eval में import करने के लिए कॉल सफलतापूर्वक किए गए लेकिन import builtins जो आप अपने exec में अनुपलब्ध बना दिया है में __import__ विधि का उपयोग करता है। यही वजह है कि आप

ImportError: __import__ not found 

print देख रहे हैं किसी भी builtins पर निर्भर नहीं करता तो ठीक काम करता है।

आप की तरह कुछ के साथ सिर्फ builtins से __import__ गुजारें सकता:

eval(obj, {'__builtins__' : {'__import__' :__builtins__.__import__}}) 
+0

ठीक है, लेकिन क्यों एक साधारण कथन (जैसा कि प्रलेखन में कहा गया है: http://docs.python.org/reference/simple_stmts.html) में उपयुक्त अंतर्निहित विधि है, और दूसरा नहीं है? क्या यह (वास्तुकला?) समाधान का कोई व्यावहारिक अर्थ है? – Tiendil

+0

'__import__' विधि मौजूद है, उदाहरण के लिए, आप इसे प्रतिस्थापित कर सकते हैं और' import' के अर्थशास्त्र को बदल सकते हैं। हालांकि यह आयात हुक का उपयोग करके बेहतर किया जाता है। देखें http://docs.python.org/library/functions.html#__import__ पायथन 3.x 'प्रिंट' में 'प्रिंट()' बिल्टिन विधि के साथ प्रतिस्थापित किया गया है ताकि आप प्रिंट 3 के साथ एक ही व्यवहार देखें। x – mikej

0

प्रिंट कार्य क्योंकि आपने 'exec' को compile फ़ंक्शन कॉल पर निर्दिष्ट किया है।

0

import वैश्विक/निर्मित __import__ फ़ंक्शन को कॉल करता है; यदि कोई नहीं मिला है, तो import विफल रहता है।

print अपने काम करने के लिए किसी भी ग्लोबल पर भरोसा नहीं करता है। यही कारण है कि print आपके उदाहरण में काम करता है, भले ही आप उपलब्ध __builtins__ का उपयोग न करें।

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