2

I have some code (that I can't easily modify), of the following form:

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

I would like to call bar(), directly, from the Python shell. I don't mind using co_globals, or other internal bits. I have the feeling that this may be impossible; is it?

JesseW
  • 1,255
  • 11
  • 19
  • The last thing that foo does is invoke bar, why not just call foo()? – PaulMcG Sep 18 '10 at 06:05
  • @paul because foo() does other stuff besides call bar(), that I don't want to do. – JesseW Sep 18 '10 at 07:25
  • "that I can't easily modify" Often false. Try talking to the author. – S.Lott Sep 18 '10 at 12:57
  • well, this is mostly just for expirmenting purposes -- if I were to actually submit it to the project (rdiff-backup), I'd certainly ask for the necessary changes to let me reuse all the code possible. – JesseW Sep 19 '10 at 00:53

1 Answers1

4

It is impossible to get at the inner function object with the code as you've stated it -- said object is only created (by the def statement) when the outer function runs (i.e., when it gets called).

As an aside, note that outer functions like foo are often coded to return the inner function as their result (e.g. by changing bar() to return bar) as the last line, exactly to work as "function factories" (often, as "closure factories") rather than keep the very existence of an internal function as a kind of private, secret implementation detail; but your coding picks the latter route instead.

Edit...:

It is possible to get at the code object for the inner function, however:

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

However, in general, to make a code object into a callable function requires considerable work (in this special case an eval suffices because the inner function has no arguments nor any nonlocal variables, but of course that's not anywhere even close to the general case... in which you do have to supply such niceties as bindings for nonlocals!-)

Alex Martelli
  • 854,459
  • 170
  • 1,222
  • 1,395
  • Hm. That's what I thought. However, it is possible to access the code object for the inner function (via `func_code.co_consts`), which leads to the question -- can I evaluate that code object? Answer: yes, with eval(). But it complains about free variables... – JesseW Sep 18 '10 at 05:30
  • thanks! The next step is figuring out how to provide the free variable to the code object. Should I make a new question to ask that, or continue in this question? – JesseW Sep 18 '10 at 05:41
  • @Jesse, it's hard enough that I recommend you open a separate Q! – Alex Martelli Sep 18 '10 at 05:52
  • Will do. Or I may just give up on it for now; I **can** just copy&paste the code, after all... ;-) Thanks so much for the help! – JesseW Sep 18 '10 at 05:55