Necesito una forma de "insertar" nombres en una función desde un bloque de código externo, por lo que son accesibles localmente y no necesitan ser manejados específicamente por el código de la función (definido como parámetros de función, cargado desde *args
etc.)Función de enlace de nombre local desde un ámbito externo
El escenario simplificado: proporciona un marco dentro del cual los usuarios pueden definir (con la menor sintaxis posible) funciones personalizadas para manipular otros objetos del marco (que son no necesariamente global
).
Idealmente, el usuario define
def user_func():
Mouse.eat(Cheese)
if Cat.find(Mouse):
Cat.happy += 1
Aquí Cat
, Mouse
y Cheese
son objetos marco que, por buenas razones, no puede ser limitada al espacio de nombres global.
Quiero escribir un contenedor para esta función se comporte de esta manera:
def framework_wrap(user_func):
# this is a framework internal and has name bindings to Cat, Mouse and Cheese
def f():
inject(user_func, {'Cat': Cat, 'Mouse': Mouse, 'Cheese': Cheese})
user_func()
return f
Entonces este envoltorio se podría aplicar a todas las funciones definidas por el usuario (como decorador, por el propio usuario o de forma automática, aunque Planeo usar una metaclase).
@framework_wrap
def user_func():
Soy consciente de nonlocal
la palabra clave del Python 3, pero todavía consideran fea (desde la perspectiva del usuario del marco) para agregar una línea adicional:
nonlocal Cat, Mouse, Cheese
y que preocuparse por la adición de todos los objetos que él necesita a esta línea.
Cualquier sugerencia es muy apreciada.
¿Cuáles son las buenas razones para no poder usar el espacio de nombres global? Si está enhebrando, puede usar el almacenamiento local de subprocesos. –
@Ivo van der Wijk: También conozco el hilo local, pero el enhebrado no es el problema aquí. Una de las razones sería que deseo que algunos nombres genéricos (como
this
) se inyecten en funciones definidas en varias clases, y para que cada clase se resuelva en algo específico de clase. Entoncesthis
no puede ser global. – onysseus@amadaeus Si la función pega algo en el dict global o usa 'global' para modificar un global, ¿quieres que ese cambio afecte al global real? – aaronasterling