Função vinculação de nome local de um escopo externo

Eu preciso de uma maneira de "injetar" nomes em uma função de um bloco de código externo, para que eles sejam acessíveis localmentee eles não precisam ser manipulados especificamente pelo código da função (definido como parâmetros da função, carregado a partir de*args etc.)

O cenário simplificado: fornecer uma estrutura na qual os usuários possam definir (com a menor sintaxe possível) funções personalizadas para manipular outros objetos da estrutura (que sãonão necessariamenteglobal)

Idealmente, o usuário define

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

AquiCat, Mouse eCheese são objetos de estrutura que, por boas razões, não podem ser limitados ao espaço para nome global.

Eu quero escrever um wrapper para esta função se comportar assim:

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

Em seguida, esse wrapper pode ser aplicado a todas as funções definidas pelo usuário (como decorador, pelo próprio usuário ou automaticamente, embora eu pretenda usar uma metaclasse).

@framework_wrap
def user_func():

Estou ciente dos Python 3'snonlocal palavra-chave, mas ainda considero feio (da perspectiva do usuário da estrutura) adicionar uma linha adicional:

nonlocal Cat, Mouse, Cheese

e se preocupar em adicionar todos os objetos que ele precisa a essa linha.

Qualquer sugestão é muito apreciada.

questionAnswers(4)

yourAnswerToTheQuestion