2010-09-18 3 views
2

У меня есть некоторый код (который я не могу легко изменить), в следующем виде:Как я могу вызвать внутреннюю функцию из оболочки Python?

def foo(x): 
    do_other_stuff_that_I_do_not_want_to_do() 
    def bar(): 
     "do something" 
     str(x) 
    bar() 

Я хотел бы назвать bar(), непосредственно из оболочки Python. Я не против использования co_globals или других внутренних битов. У меня такое ощущение, что это невозможно. это?

+0

Последней вещью, что Foo делает это вызвать панель, почему просто не назвать Foo()? – PaulMcG

+0

@paul, потому что foo() делает другие вещи помимо call bar(), которые я не хочу делать. – JesseW

+0

", что я не могу легко изменить" Часто ложно. Попробуйте поговорить с автором. –

ответ

4

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

Как и в сторону, отметим, что внешние функции, такие как foo часто закодированы для возвращения внутренней функции в качестве результата (например, путем изменения bar() к return bar) в последней строке, точно работать в качестве «функциональных заводов» (часто , как «фабрики закрытия»), а не сохранить само существование внутренней функции как своего рода частной, секретной детали реализации; но ваша кодировка выбирает последний маршрут.

Редактировать ...:

Это является можно получить в кода объекта для внутренней функции, однако:

>>> def outer(): 
... def inner(): return 'boo' 
... print inner() 
... 
>>> eval(outer.func_code.co_consts[1]) 
'boo' 
>>> 

Однако, в целом, чтобы сделать кодовый объект в вызываемой функции требует значительной работы (в этом специальном случае достаточно eval, потому что внутренняя функция не имеет аргументов или нелокальных переменных, но, конечно, это нет в любом месте, даже близко к общему случаю ..., в которой вы должны предоставить такие тонкости, как крепления для nonlocals -!)

+0

Hm. Это то, о чем я думал. Тем не менее, можно получить доступ к кодовому объекту для внутренней функции (через 'func_code.co_consts'), что приводит к вопросу - могу ли я оценить этот объект кода? Ответ: да, с eval(). Но он жалуется на свободные переменные ... – JesseW

+0

спасибо! Следующий шаг - выяснить, как предоставить свободную переменную объекту кода. Должен ли я задать новый вопрос, чтобы спросить об этом или продолжить этот вопрос? – JesseW

+0

@ Джесс, это достаточно сложно, что я рекомендую вам открыть отдельный Q! –

Смежные вопросы