2010-09-18 24 views
2

J'ai un peu de code (que je ne peux pas modifier facilement), de la forme suivante:Comment puis-je appeler une fonction interne du shell Python?

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

Je voudrais appeler bar(), directement, à partir du shell Python. Je ne me dérange pas en utilisant co_globals, ou d'autres bits internes. J'ai le sentiment que cela peut être impossible; est-ce?

+0

La dernière chose que foo n'Invoke bar, pourquoi ne pas simplement appeler foo()? – PaulMcG

+0

@paul parce que foo() fait autre chose que call bar(), ce que je ne veux pas faire. – JesseW

+0

"que je ne peux pas facilement modifier" Souvent faux. Essayez de parler à l'auteur. –

Répondre

4

Il est impossible d'obtenir à l'objet fonction intérieure avec le code que vous l'avez dit - ledit objet est créé uniquement (par l'instruction def) lorsque la fonction externe fonctionne (quand elle est appelé).

En aparté, notez que les fonctions externes comme foo sont souvent codées à retour la fonction intérieure que leur résultat (par exemple en changeant bar()-return bar) comme la dernière ligne, exactement à travailler comme « usines de fonction » (souvent , comme "usines de fermeture") plutôt que de garder l'existence même d'une fonction interne comme une sorte de détail d'implémentation privée et secrète; mais votre codage choisit la dernière route à la place.

Modifier ...:

Il est possible d'obtenir à l'objet de code pour la fonction intérieure, cependant:

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

Cependant, en général, de faire un code objet dans une fonction appelable nécessite un travail considérable (dans ce cas particulier un eval suffit car la fonction interne n'a pas d'arguments ni de variables non locales, mais bien sûr pas partout même près au cas général ... dans laquelle vous ne devez fournir de telles subtilités comme fixations pour nonlocals -)

+0

Hm. C'est ce que je pensais. Cependant, il est possible d'accéder à l'objet code pour la fonction interne (via func_code.co_consts), ce qui conduit à la question: puis-je évaluer cet objet code? Réponse: oui, avec eval(). Mais il se plaint de variables libres ... – JesseW

+0

merci! L'étape suivante consiste à déterminer comment fournir la variable libre à l'objet code. Devrais-je poser une nouvelle question à poser ou continuer dans cette question? – JesseW

+0

@Jesse, il est assez difficile que je vous recommande d'ouvrir un Q distinct! –