函数内部的函数 - 每次?
Posted
技术标签:
【中文标题】函数内部的函数 - 每次?【英文标题】:Function inside function - every time? 【发布时间】:2013-04-08 12:09:37 【问题描述】:让我们有这个代码:
def big_function():
def little_function():
.......
.........
Python 文档中提到了def
声明:
函数定义是一个可执行语句。它的执行绑定 函数名...
所以,问题是:
def little_function()
每次调用big_function
时都会执行吗?
问题是关于 def
声明,而不是 little_function()
正文。
【问题讨论】:
【参考方案1】:内部函数中的代码只编译一次,因此不会有显着的运行时损失。
每次调用外部函数时,只有内部函数 closure 会更新。例如,请参阅here,了解有关闭包的更多详细信息。
这是一个快速演示,检查闭包:
def f(x):
a = []
b = x + 1
def g():
print a, b
return g
In [28]: y = f(5)
In [29]: y
Out[29]: <function __main__.g>
In [30]: y.func_closure
Out[30]:
(<cell at 0x101c95948: list object at 0x101c3a3f8>,
<cell at 0x101c958a0: int object at 0x100311aa0>)
In [31]: y.func_closure[1].cell_contents
Out[31]: 6
【讨论】:
【参考方案2】:您可以使用dis
模块检查字节码:
>>> import dis
>>> def my_function():
... def little_function():
... print "Hello, World!"
...
...
>>> dis.dis(my_function)
2 0 LOAD_CONST 1 (<code object little_function at 0xb74ef9f8, file "<stdin>", line 2>)
3 MAKE_FUNCTION 0
6 STORE_FAST 0 (little_function)
9 LOAD_CONST 0 (None)
12 RETURN_VALUE
如您所见,内部函数的代码只编译一次。每次调用 my_function
时它都会被加载并创建一个新的函数对象(在这个意义上,def little_function
is 每次调用 my_function
时都会执行),但这并没有增加太多开销。
【讨论】:
你怎么知道执行MAKE_FUNCTION
字节码指令涉及多少开销?似乎它可能需要分配内存,这在大多数其他语言中通常是一个缓慢的操作。
@martineau 不,没有大的内存分配。 MAKE_FUNCTION
操作只是增加了代码对象的参考代码,它不必复制。肯定会创建一个新的函数对象,这涉及分配一个新的PyFunctionObject
,但考虑到 每个 操作都会分配 python 对象,它不会“显着”损害性能(显然,重要的是取决于其余的my_function
的代码)。以上是关于函数内部的函数 - 每次?的主要内容,如果未能解决你的问题,请参考以下文章