我们可以使用外部函数在python中访问其外部函数范围之外的内部函数吗?

时间:2012-07-24 07:16:46

标签: python function 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 个答案:

答案 0 :(得分:6)

>>> 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

答案 1 :(得分:4)

如果将内部函数作为值返回

,则可以
>>> def main():
...     def sub():
...         a = 5
...         print a
...     return sub
...
>>> inner = main()
>>> inner()
5

或者您可以将它作为属性附加到main(函数毕竟是对象):

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

但是你最好记录下你这样做的理由,因为几乎肯定会让任何人读到你的代码时感到惊讶: - )

答案 2 :(得分:1)

函数只是Python中的另一个对象,可以进行内省。

您可以在运行时获取外部函数体并解析/评估它以使该函数在当前命名空间中可用。

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

与调用outer.inner()并不是一回事,但是如果你没有在外部函数的范围之外明确地使用内部函数,我想这是唯一的可能性。

例如,一个非常天真的评估尝试可能是:

>>> exec('\n'.join([ line[4:] for line in inspect.getsourcelines(outer)[0][1:] ]))
>>> inner()
hello!

答案 3 :(得分:0)

不,你不能。内部函数不是外部函数的属性。

内部函数仅在执行def语句后执行(执行外部函数时),并且在函数退出时停止存在。

当然,你可以return内部功能。

答案 4 :(得分:0)

内部函数只是一个局部变量,因此适用相同的规则。如果你想访问它,你必须退回它。