在Python中嵌套函数时有开销吗?

2024-04-16 13:25:48 发布

您现在位置:Python中文网/ 问答频道 /正文

在Python中,如果父函数中有一个子函数,那么每次调用父函数时,子函数是否“初始化”(创建)?在另一个函数中嵌套一个函数是否有相关的开销?


Tags: 函数子函数
3条回答

这是一个影响,但在大多数情况下,它是如此之小,你不必担心它-大多数非平凡的应用程序可能已经有性能瓶颈,其影响比这个大几个数量级。而是担心代码的可读性和可重用性。

这里有些代码比较了每次通过循环重新定义函数与重用预定义函数的性能。

import gc
from datetime import datetime

class StopWatch:
     def __init__(self, name):
         self.name = name

     def __enter__(self):
         gc.collect()
         self.start = datetime.now()

     def __exit__(self, type, value, traceback):
         elapsed = datetime.now()-self.start
         print '** Test "%s" took %s **' % (self.name, elapsed)

def foo():
     def bar():
          pass
     return bar

def bar2():
    pass

def foo2():
    return bar2

num_iterations = 1000000

with StopWatch('FunctionDefinedEachTime') as sw:
    result_foo = [foo() for i in range(num_iterations)]

with StopWatch('FunctionDefinedOnce') as sw:
    result_foo2 = [foo2() for i in range(num_iterations)]

当我在运行OS X Lion的Macbook Air上运行Python2.7时,我得到:

** Test "FunctionDefinedEachTime" took 0:00:01.138531 **
** Test "FunctionDefinedOnce" took 0:00:00.270347 **

是的,每次都会创建一个新对象。除非你把事情搞得很紧,否则这很可能不是问题。分析会告诉你是否有问题。

In [80]: def foo():
   ....:     def bar():
   ....:         pass
   ....:     return bar
   ....: 

In [81]: id(foo())
Out[81]: 29654024

In [82]: id(foo())
Out[82]: 29651384

代码对象是预编译的,因此部分没有开销。函数对象建立在每次调用的基础上——它将函数名绑定到代码对象,记录默认变量等

执行摘要:这不是免费的。

>>> from dis import dis
>>> def foo():
        def bar():
                pass
        return bar

>>> dis(foo)
  2           0 LOAD_CONST               1 (<code object bar at 0x1017e2b30, file "<pyshell#5>", line 2>)
              3 MAKE_FUNCTION            0
              6 STORE_FAST               0 (bar)

  4           9 LOAD_FAST                0 (bar)
             12 RETURN_VALUE 

相关问题 更多 >