определение функций в декораторе - PullRequest
1 голос
/ 17 июля 2009

Почему это не работает? Как я могу заставить это работать? То есть, как я могу сделать гу доступным внутри моей украшенной функции?

def decorate(f):
    def new_f():
        def gu():
            pass
        f()
    return new_f

@decorate
def fu():
    gu()

fu()

Нужно ли как-нибудь добавлять gu в словарь определенных функций? Или я могу добавить gu в локальное пространство имен f перед вызовом?

Ответы [ 5 ]

2 голосов
/ 17 июля 2009

Если вам нужно передать gu в fu, вам нужно сделать это явно с помощью параметров:

def decorate(f):
    def new_f():
        def gu():
            pass
        f(gu)
    return new_f

@decorate
def fu(gu):
    gu()

fu()
1 голос
/ 17 июля 2009

gu () определяется только в new_f (). Если вы не вернете его или не привяжете к new_f () или к чему-то еще, на него нельзя ссылаться извне new_f ()

Я не знаю, чем вы занимаетесь, но эта схема кажется очень сложной. Может быть, вы можете найти менее сложное решение.

1 голос
/ 17 июля 2009

gu локально для функции new_f , которая локальна для функции украшать .

0 голосов
/ 17 июля 2009

Почему бы не сделать ваш декоратор классом, а не функцией? По-видимому, это возможно, как я обнаружил, когда просматривал справку для встроенного property. (Раньше я думал, что вы можете просто применять декораторы к классам, а не то, что сами декораторы могут быть классами.)

(Конечно, gu должен быть методом класса или внутреннего класса.)

0 голосов
/ 17 июля 2009

В принципе, вы можете создать новую функцию, используя тот же код, что и старый, но заменив глобальную область видимости измененной:

import new

def with_bar(func):
    def bar(x):
        return x + 1
    f_globals = func.func_globals.copy()
    f_globals['bar'] = bar
    return new.function(func.func_code, f_globals,
                        func.func_name, func.func_defaults, func.func_closure)

@with_bar
def foo(x):
    return bar(x)

print foo(5) # prints 6

На практике вы действительно должны найти лучший способ сделать это. Передача функций в качестве параметров является одним из вариантов. Могут быть и другие подходы, но трудно сказать, что подойдет, без описания проблемы высокого уровня.

...