Buscar..


Sintaxis

  • eval (expresión [, globals = None [, locals = None]])
  • exec (objeto)
  • exec (objeto, globals)
  • exec (objeto, globales, locales)

Parámetros

Argumento Detalles
expression El código de expresión como una cadena o un objeto de code
object El código de la declaración como una cadena, o un objeto de code
globals El diccionario a utilizar para variables globales. Si no se especifican los locales, esto también se usa para los locales. Si se omite, se utilizan los globals() del ámbito de llamada.
locals Un objeto de mapeo que se utiliza para las variables locales. Si se omite, se usa el que se pasa para los globals . Si se omiten ambos, entonces se utilizan los globals() y locals() del ámbito de llamada para los globals y locals respectivamente.

Observaciones

En exec , si los globals son locals (es decir, se refieren al mismo objeto), el código se ejecuta como si estuviera en el nivel del módulo. Si los elementos globals y locals son objetos distintos, el código se ejecuta como si estuviera en un cuerpo de clase .

Si las globals de objeto se pasa en, pero no especifica __builtins__ clave, entonces Python funciones integradas y los nombres se añaden automáticamente al ámbito global. Para suprimir la disponibilidad de funciones como la print o la isinstance en el ámbito ejecutado, permita que los globals tengan la clave __builtins__ asignada al valor None . Sin embargo, esto no es una característica de seguridad.

La sintaxis específica de Python 2 no debe usarse; La sintaxis de Python 3 funcionará en Python 2. Por lo tanto, los siguientes formularios están en desuso: <s>

  • exec object
  • exec object in globals
  • exec object in globals, locals

Evaluando declaraciones con exec

>>> code = """for i in range(5):\n    print('Hello world!')"""
>>> exec(code)
Hello world!
Hello world!
Hello world!
Hello world!
Hello world!

Evaluando una expresión con eval

>>> expression = '5 + 3 * a'
>>> a = 5
>>> result = eval(expression)
>>> result
20

Precompilando una expresión para evaluarla varias veces.

compile función incorporada de compile se puede utilizar para precompilar una expresión en un objeto de código; este objeto de código se puede pasar a eval. Esto acelerará las ejecuciones repetidas del código evaluado. El tercer parámetro para compile debe ser la cadena 'eval' .

>>> code = compile('a * b + c', '<string>', 'eval')
>>> code
<code object <module> at 0x7f0e51a58830, file "<string>", line 1>
>>> a, b, c = 1, 2, 3
>>> eval(code)
5

Evaluar una expresión con eval utilizando globales personalizados

>>> variables = {'a': 6, 'b': 7}
>>> eval('a * b', globals=variables)
42

Como un plus, con esto el código no puede referirse accidentalmente a los nombres definidos fuera:

>>> eval('variables')
{'a': 6, 'b': 7}
>>> eval('variables', globals=variables)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1, in <module>
NameError: name 'variables' is not defined

El uso de defaultdict permite, por ejemplo, tener variables indefinidas configuradas en cero:

>>> from collections import defaultdict
>>> variables = defaultdict(int, {'a': 42})
>>> eval('a * c', globals=variables)  # note that 'c' is not explicitly defined
0

Evaluar una cadena que contiene un literal de Python con ast.literal_eval

Si tiene una cadena que contiene literales de Python, como cadenas, flotadores, etc., puede usar ast.literal_eval para evaluar su valor en lugar de eval . Esto tiene la característica adicional de permitir solo cierta sintaxis.

>>> import ast
>>> code = """(1, 2, {'foo': 'bar'})"""
>>> object = ast.literal_eval(code)
>>> object
(1, 2, {'foo': 'bar'})
>>> type(object)
<class 'tuple'>

Sin embargo, esto no es seguro para la ejecución del código proporcionado por un usuario no confiable, y es trivial bloquear un intérprete con una entrada cuidadosamente diseñada

>>> import ast
>>> ast.literal_eval('()' * 1000000)
[5]    21358 segmentation fault (core dumped)  python3

Aquí, la entrada es una cadena de () repetida un millón de veces, lo que provoca un bloqueo en el analizador CPython. Los desarrolladores de CPython no consideran los errores en el analizador como problemas de seguridad.

Código de ejecución proporcionado por un usuario no confiable que utiliza exec, eval o ast.literal_eval

No es posible usar eval o exec para ejecutar código de un usuario no confiable de forma segura. Incluso ast.literal_eval es propenso a bloqueos en el analizador. A veces es posible protegerse contra la ejecución de código malicioso, pero no excluye la posibilidad de bloqueos directos en el analizador o el tokenizador.

Para evaluar el código por un usuario que no es de confianza, debe recurrir a algún módulo de terceros, o tal vez escribir su propio analizador y su propia máquina virtual en Python.



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow