Почему я могу назвать «печать» из «eval» - PullRequest
7 голосов
/ 16 октября 2010

Для кода:

#!/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

И print, и import являются языковой конструкцией. Почему 'eval' ограничивает использование 'import', но не ограничивает 'print'?

P.S. Я использую Python 2.6

ОБНОВЛЕНИЕ: Вопрос не в том, почему импорт не работает? но "Почему работает печать?" Есть какие-то архитектурные ограничения или что-то еще?

Ответы [ 4 ]

7 голосов
/ 16 октября 2010

Метод __import__ вызывается ключевым словом import: python.org

Если вы хотите иметь возможность импортировать модуль, вам необходимо оставить __import__Метод во встроенных:

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

obj = compile(src, '', 'exec')
eval(obj, {'__builtins__': {'__import__':__builtins__.__import__}})
2 голосов
/ 16 октября 2010

В вашем eval вызов import сделан успешно, однако import использует метод __import__ в встроенных функциях, которые вы сделали недоступными в вашем exec.Это причина, по которой вы видите, что

ImportError: __import__ not found

print не зависит от каких-либо встроенных функций, поэтому работает нормально.

Вы можете передать только __import__ из встроенных компонентов с чем-то вроде:

eval(obj, {'__builtins__' : {'__import__' :__builtins__.__import__}})
0 голосов
/ 18 октября 2010

import вызывает глобальную / встроенную функцию __import__; если его нет, import завершается неудачей.

print не использует глобальные функции для своей работы. Вот почему print работает в вашем примере, даже если вы не используете доступные __builtins__.

0 голосов
/ 16 октября 2010

печать работает, потому что вы указали 'exec' для вызова функции compile.

...