Enlace de nombre local de función desde un ámbito externo

Necesito una forma de "inyectar" nombres en una función desde un bloque de código externo, para que sean accesibles localmentey no necesitan ser manejados específicamente por el código de la función (definido como parámetros de la función, cargados desde*args etc.)

El escenario simplificado: proporcionar un marco dentro del cual los usuarios pueden definir (con la menor sintaxis posible) funciones personalizadas para manipular otros objetos del marco (que sonno necesariamenteglobal)

Idealmente, el usuario define

def user_func():
    Mouse.eat(Cheese)
    if Cat.find(Mouse):
        Cat.happy += 1

aquíCat, Mouse yCheese son objetos de marco que, por buenas razones, no pueden vincularse al espacio de nombres global.

Quiero escribir un contenedor para que esta función se comporte así:

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

Luego, este contenedor podría aplicarse a todas las funciones definidas por el usuario (como decorador, por el propio usuario o automáticamente, aunque planeo usar una metaclase).

@framework_wrap
def user_func():

Soy consciente de los Python 3nonlocal palabra clave, pero todavía considero feo (desde la perspectiva del usuario del marco) agregar una línea adicional:

nonlocal Cat, Mouse, Cheese

y preocuparse por agregar cada objeto que necesita a esta línea.

Cualquier sugerencia sera grandemente apreciada.

Respuestas a la pregunta(4)

Su respuesta a la pregunta