La función creada dinámicamente en Python f(2) no se puede resolver (f1)

Intente crear dinámicamente dos funciones definidas en una cadena. Código:

def  main():

    fns = '''
    def plus_one(x):
    return x + 1


    def plus_two(x):
    return plus_one(x) + 1

    '''
    exec(fns)

    result = eval('plus_two(11)')

    print(result)

if __name__ == '__main__':
    main()

Guardar este código en dyn_code.pyun archivo con nombre y ejecutarlo genera el siguiente error:

python dyn_code.py  
Traceback (most recent call last):   
File "dyn_code.py", line 19, in <module>
main()   
File "dyn_code.py", line 14, in main   
result = eval('plus_two(11)')
File "<string>", line 1, in <module>   
File "<string>", line 7, in plus_two 
NameError: name 'plus_one' is not defined

El problema aquí plus_oneno plus_twose puede resolver internamente. Sabes

plus_oneen sí está bien aquí y se puede llamar con los resultados correctos. Sabes

¿Alguien puede decirme cómo inyectar código como este en un espacio de nombres local? Específicamente, quiero crear dos funciones, una de las cuales hace referencia a la otra. Sabes

Utilicé intencionalmente las formas más abiertas de execy eval, sabía cómo restringirlas, etc. También verifiqué execque ambas funciones existen en el espacio de nombres local después de la llamada. Sabes

¡Lo que es aún más frustrante es que el código funciona bien en la sesión del intérprete! Es decir, después de execinyectar estas dos funciones en el espacio de nombres del intérprete, plus_twono hay problemas en tiempo de ejecución. Sabes

Idealmente, me gustaría evitar el uso de funciones en escenarios de funciones.

def plus_two(x):
    def plus_one(x):
        return x + 1

    return plus_one(x) + 1

Esta técnica realmente funciona, pero necesito dos funciones independientes nombradas explícitamente.

Es necesario exec()agregar un diccionario a la llamada a globals(). También puedes omitir la llamada eval a plus_two, así:

def  main():
    exec('def plus_one(x):\n    return x + 1\n\ndef plus_two(x):    return plus_one(x) + 1', globals())
    print(plus_two(11))

if __name__ == '__main__':
    main()

 

おすすめ

転載: blog.csdn.net/xifenglie123321/article/details/132186715