5

只是出于好奇,我想知道这一点。
我知道内部函数的范围仅限于外部函数体,但仍然有任何方法可以让我们在其范围之外访问内部函数变量或在外部调用内部函数它的范围?

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]: 
4

5 回答 5

7
>>> 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
于 2012-07-24T07:33:07.240 回答
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

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

于 2012-07-24T07:28:25.020 回答
1

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

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

当然,您可以return使用内部功能。

于 2012-07-24T07:29:17.110 回答
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() 并不是一回事,但如果您没有使内部函数在外部函数范围之外显式可用,我想这是唯一的可能性。

例如,一个非常幼稚的 eval 尝试可能是:

>>> exec('\n'.join([ line[4:] for line in inspect.getsourcelines(outer)[0][1:] ]))
>>> inner()
hello!
于 2012-07-24T07:46:15.140 回答
0

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

于 2012-07-24T07:34:09.423 回答