我有一个关于Python中函数调用的问题。假设我想编写一个名为superLongFunc(expr)的函数。这个函数很长,很难调试。为了更好的可读性,我想把函数拆分成更小的辅助函数,比如smallFunc1(expr)、smallFunc2(expr
我的问题是,这会影响代码的性能吗?调用函数在Python中究竟是如何工作的?Python是否通过引用将变量传递给函数?还是在将变量提供给函数之前先复制变量?
我知道这是一个很棘手的问题,但它已经困扰了我一段时间了。提前感谢!
Python使用一个有时被对象调用的系统。将参数传递给函数时,不会复制任何内容。函数参数的名称在函数体中本地绑定到函数调用中提供的相同对象。
这与大多数人认为的"按值调用"不同,因为它不会复制对象。但它也不同于"通过引用调用",因为引用是对对象的——绑定了一个新的名称,但绑定到了同一个对象。这意味着您可以更改传入的对象,但在函数内重新绑定名称在函数外没有任何效果。区别的一个简单例子:
>>> def func(x):
... x[0] = 2 # Mutating the object affects the object outside the function
>>> myList = [1]
>>> func(myList)
>>> myList # myList has changed
[2]
>>> def func(x):
... x = 2 # rebinding name has no effect outside the function
>>> myList = [1]
>>> func(myList)
>>> myList # myList is unaffected
[1]
我对此的简单思考方式是,对裸名称的赋值——也就是name = value
形式的语句——与Python中的其他语句完全不同。操作名称而非值的唯一方法是执行name = value
。(也有一些挑剔的例外,比如摆弄globals()
等等,但无论如何,这些都是危险的领域。)特别是name = value
不同于obj.prop = value
、obj[0] = value
、obj += value
和其他类似的东西,它们看起来像赋值,但实际上是对对象而不是名称进行操作。
也就是说,Python中的函数调用本身就有一定的开销(用于设置执行框架等)。如果一个函数被多次调用,这种开销可能会对性能产生显著影响。因此,将一个函数拆分为多个函数仍然可能对性能产生影响,因为每次额外的函数调用都会增加一些开销。