Python - 传递值是如何工作的? [英] Python - how does passing values work?

查看:32
本文介绍了Python - 传递值是如何工作的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个关于 Python 中函数调用的问题.假设我想编写一个名为 superLongFunc(expr) 的函数.该函数超长而且很难调试.我想将该函数拆分为更小的辅助函数以提高可读性,例如 smallFunc1(expr)、smallFunc2(expr) 等.

我的问题是,这会影响代码的性能吗?调用函数在 Python 中究竟是如何工作的?Python 是否通过引用将变量传递给函数?或者它是否在将变量提供给函数之前复制了它?

我知道这是一个非常愚蠢的问题,但它一直困扰着我一段时间.提前致谢!

解决方案

Python 使用有时称为 call-by 的系统-对象.将参数传递给函数时,不会复制任何内容.函数参数的名称在函数体内局部绑定到函数调用中提供的相同对象.

这与大多数人认为的按值调用"不同,因为它不复制对象.但它也不同于按引用调用",因为引用是对 object 的——绑定了一个新的 name,但绑定到同一个对象.这意味着您可以改变传入的对象,但在函数内部重新绑定名称在函数外部没有影响.区别的一个简单例子:

<预><代码>>>>定义函数(x):... x[0] = 2 # 改变对象会影响函数外的对象>>>我的列表 = [1]>>>功能(我的列表)>>>myList # myList 已更改[2]>>>定义函数(x):... x = 2 # 重新绑定名称在函数外无效>>>我的列表 = [1]>>>功能(我的列表)>>>myList # myList 不受影响[1]

我对此的简单思考方式是对裸名的赋值——即 name = value 形式的语句 --- 与 Python 中的所有其他内容完全不同.对名称而不是值进行操作的唯一方法是执行 name = value.(对此有一些挑剔的例外,例如使用 globals() 等等,但无论如何这些都是危险的领域.)特别是 name = valueobj.prop = valueobj[0] = valueobj += value 和其他类似的东西,看起来像赋值但实际操作对象而不是名称.

也就是说,Python 中的函数调用本身就有一定的开销(用于设置执行框架等).如果一个函数被多次调用,这种开销会导致明显的性能影响.因此,将一个函数拆分为多个函数仍然会对性能产生影响,因为每个额外的函数调用都会增加一些开销.

I have a question about function calls in Python. Say I want to write a function called superLongFunc(expr). The function is super long and really hard to debug. I want to split the function into smaller helper functions for better readability, to something like smallFunc1(expr),smallFunc2(expr), etc.

My question is, does this affect the performance of the code at all? How exactly does calling functions work in Python? Does Python pass the variables to a function by reference? Or does it make a copy of the variable before feeding it to the function?

I know it's a pretty nooby question but it's been bugging me for a while. Thanks in advance!

解决方案

Python uses a system sometimes called call-by-object. Nothing is copied when you pass arguments to a function. The names of the function arguments are locally bound within the function body, to the same objects provided in the function call.

This is different from what most people think of as "call by value", because it doesn't copy the objects. But it's also different from "call by reference" because the reference is to the object --- a new name is bound, but to the same object. This means that you can mutate the passed-in object, but rebinding the name inside the function has no effect outside the function. A simple example of the difference:

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

My simple way of thinking about this is that assignment to a bare name --- that is, statements of the form name = value --- is completely different from everything else in Python. The only way to operate on names and not on values is to do name = value. (There are nitpicky exceptions to this, like mucking around with globals() and so on, but these are dangerous territory anyway.) In particular name = value is different from obj.prop = value, obj[0] = value, obj += value, and other similar things that look like assignment but actually operate on objects and not on names.

That said, function calls in Python have a certain amount of overhead just in themselves (for setting up the execution frame, etc.). If a function is called many times, this overhead can cause a noticeable performance impact. So splitting one function into many could still have a performance impact, since each additional function call will add some overhead.

这篇关于Python - 传递值是如何工作的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆