2010-10-16 15 views
6

Para el código:qué puedo llamar 'imprimir' desde 'eval'

#!/usr/bin/python 

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

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

me sale de salida:

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

Tanto 'imprimir' e 'importación' son construcción del lenguaje. ¿Por qué 'eval' restringe el uso de 'import' pero no restringe 'print'?

P.S. Estoy usando Python 2.6

ACTUALIZACIÓN: La pregunta no es "¿Por qué la importación no funciona?" pero "¿Por qué funciona la impresión?" ¿Hay algunas restricciones de arquitectura u otra cosa?

Respuesta

6

El método __import__ es invocado por el import palabra clave: python.org

Si usted quiere ser capaz de importar un módulo que necesitas abandonar el método __import__ en las órdenes internas:

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

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

La pregunta no es "¿Por qué la importación no funciona?" pero "¿Por qué funciona la impresión?" – Tiendil

+0

print se convierte en un método en python 3k, apuesto a que ya no funcionará :) – Sacha

2

En su eval la llamada a import se realiza correctamente sin embargo import hace uso del método __import__ de órdenes internas que ha hecho disponible en su exec. Esta es la razón por la que está viendo

ImportError: __import__ not found 

print no depende de ningún modo builtins funciona bien.

Usted podría pasar simplemente __import__ de órdenes internas con algo como:

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

Bien, pero ¿por qué una declaración simple (como se dice en la documentación: http://docs.python.org/reference/simple_stmts.html) tiene el método de compilación adecuado, y otra no? ¿Tiene esta solución (arquitectónica?) Algún significado práctico? – Tiendil

+0

existe el método '__import__' por lo que, por ejemplo, puede reemplazarlo y cambiar la semántica de' import'. Sin embargo, esto se hace mejor usando ganchos de importación. Ver http://docs.python.org/library/functions.html#__import__ En Python 3.x 'print' ha sido reemplazado con el método' print() 'incorporado para que pueda ver el mismo comportamiento con print in 3. x – mikej

0

trabajo de impresión s porque ha especificado 'exec' en la llamada a la función compile.

0

import llama a la función global/integrada __import__; si no hay ninguno, import falla.

print no depende de ningún planeta para hacer su trabajo. Es por eso que print funciona en su ejemplo, aunque no utilice el __builtins__ disponible.

Cuestiones relacionadas