La porción de buenas respuestas aquí, pero ninguno describen el uso de eval
en el contexto de es globals=
y locals=
kwargs. Estos pueden usarse para limitar los métodos que están disponibles a través del método eval
. Por ejemplo si se carga un intérprete de python fresca del locals()
globals()
y será el mismo y ser algo como esto:
>>> globals()
{'__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__doc__': None,
'__spec__': None, '__builtins__': <module 'builtins' (built-in)>,
'__package__': None, '__name__': '__main__'}
sin duda hay métodos dentro del módulo de builtins
que puede hacer un daño significativo a un sistema. Pero es posible bloquear todo y todo lo que no queremos disponible. Tomemos un ejemplo. Digamos que queremos construir una lista para representar un dominio de los núcleos disponibles en un sistema. Para mí tengo 8 núcleos, así que me gustaría una lista [1, 8]
.
>>>from os import cpu_count()
>>>eval('[1, cpu_count()'])
[1, 8]
Del mismo modo todos __builtins__
está disponible.
>>>eval('abs(-1)')
1
Ok. Entonces, vemos un método que queremos exponer y un ejemplo de uno (de muchos que pueden ser mucho más insidiosos) método que no queremos exponer. Entonces bloqueemos todo.
>>>eval('[1, cpu_count()]', {'__builtins__':None}, {})
TypeError: 'NoneType' object is not subscriptable
Hemos bloqueado en la práctica todos los métodos __builtins__
y como tal traído un nivel de protección en nuestro sistema. En este punto, podemos comenzar a agregar nuevamente en los métodos que queremos expuestos.
>>>from os import cpu_count
>>>exposed_methods = {'cpu_count': cpu_count}
>>>eval('cpu_count()', {'__builtins__':None}, exposed_methods)
8
>>>eval('abs(cpu_count())', {'__builtins__':None}, exposed_methods)
TypeError: 'NoneType' object is not subscriptable
Ahora tenemos el método cpu_count disponible y seguimos bloqueando todo lo que no queremos. En mi opinión, esto es súper poderoso y claramente desde el alcance de las otras respuestas no es una implementación común. Existen numerosos usos para algo como esto y siempre que se maneje correctamente, personalmente creo que el eval
se puede usar de forma segura con un gran valor.
N.B.
Algo más que es genial acerca de estos kwargs
es que puede comenzar a usar la abreviatura de su código. Supongamos que usa eval como parte de una canalización para ejecutar algún texto importado. El texto no necesita tener un código exacto, puede seguir un formato de archivo de plantilla y aún ejecutar cualquier cosa que desee. Por ejemplo:
>>>from os import cpu_count
>>>eval('[1,cores]', {'__builtins__': None}, {'cores': cpu_count()})
[1, 8]
¿Es eso un libro de Python 3.x un 2.x uno? De cualquier manera, tal uso liberal de 'eval' sugiere que es un libro horrible. – delnan
erm, solo me pregunto ... ¿por qué esto fue aprobado? No me quejo, solo quiero mejorar mis preguntas. – Billjk
Tu libro suena terrible. Debería encontrar un mejor libro, tal vez http://www.greenteapress.com/thinkpython/html/index.html –