Can we access inner function outside its scope of

2019-06-24 02:07发布

Just for the sake of curiosity I wanna know this..
I know scope of inner function is limited to outer function body only, but still is there any way so that we can access the inner function variable outside its scope or call the inner function outside its scope ?

In [7]: def main():
   ...:     def sub():
   ...:         a=5
   ...:         print a
   ...:         

In [8]: main()

In [9]: main.sub()
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
/home/dubizzle/webapps/django/dubizzle/<ipython-input-9-3920726955bd> in <module>()
----> 1 main.sub()

AttributeError: 'function' object has no attribute 'sub'

In [10]: 

5条回答
家丑人穷心不美
2楼-- · 2019-06-24 02:34

No, you can't. The inner function is not an attribute of the outer function.

The inner function only exists after its def statement is executed (while the outer function is executed), and it stops to exist when the function exits.

You could return the inner function, of course.

查看更多
我欲成王,谁敢阻挡
3楼-- · 2019-06-24 02:36

A function is just another object in Python and can be introspected.

You can get the outer function body at runtime and parse/eval it to make the function available in the current namespace.

>>> import inspect
>>> def outer():
        def inner():
            print "hello!"
>>> inspect.getsourcelines(outer)
([u'def outer():\n', u'    def inner():\n', u'        print "hello!"\n'], 1)

Not really the same thing as calling outer.inner(), but if you are not making the inner function explicitly available outside the scope of the outer function, I guess it is the the only possibility.

For example, a very naive eval attempt could be:

>>> exec('\n'.join([ line[4:] for line in inspect.getsourcelines(outer)[0][1:] ]))
>>> inner()
hello!
查看更多
啃猪蹄的小仙女
4楼-- · 2019-06-24 02:42
>>> def main():
...     def sub():
...         a=5
...         print a
... 
>>> main.__code__.co_consts
(None, <code object sub at 0x2111ad0, file "<stdin>", line 2>)
>>> exec main.__code__.co_consts[1]
5
查看更多
地球回转人心会变
5楼-- · 2019-06-24 02:45

You can if you return the inner function as a value

>>> def main():
...     def sub():
...         a = 5
...         print a
...     return sub
...
>>> inner = main()
>>> inner()
5

or you can attach it to main as a property (functions are objects after all):

>>> def main():
...     def sub():
...         a = 5
...         print a
...     main.mysub = sub
...
>>> main()
>>> main.mysub()
5

but you better document your very good reason for doing this, since it will almost certainly surprise anyone reading your code :-)

查看更多
可以哭但决不认输i
6楼-- · 2019-06-24 02:45

An inner function is just a local variable like any other so the same rules apply. If you want to access it you have to return it.

查看更多
登录 后发表回答