参数是按引用传递还是按值传递?我如何通过引用传递,以便下面的代码输出 'Changed'
而不是 'Original'
?
class PassByReference:
def __init__(self):
self.variable = 'Original'
self.change(self.variable)
print(self.variable)
def change(self, var):
var = 'Changed'
原文由 David Sykes 发布,翻译遵循 CC BY-SA 4.0 许可协议
参数 通过赋值传递。这背后的理由是双重的:
所以:
如果你将一个 可变 对象传递给一个方法,该方法会得到对同一个对象的引用,你可以随心所欲地改变它,但如果你在方法中重新绑定引用,外部作用域将一无所知,之后大功告成,外部引用仍将指向原始对象。
如果将 不可变 对象传递给方法,仍然无法重新绑定外部引用,甚至无法改变对象。
为了更清楚地说明,让我们举一些例子。
列表 - 可变类型
让我们尝试修改传递给方法的列表:
输出:
由于传入的参数是对
outer_list
的引用,而不是它的副本,我们可以使用变异列表方法来更改它并将更改反映在外部范围中。现在让我们看看当我们尝试更改作为参数传入的引用时会发生什么:
输出:
由于
the_list
参数是按值传递的,因此为其分配新列表对方法外部的代码看不到任何影响。 Thethe_list
was a copy of theouter_list
reference, and we hadthe_list
point to a new list, but there was no way to change whereouter_list
指出。字符串 - 不可变类型
它是不可变的,所以我们无法更改字符串的内容
现在,让我们尝试更改参考
输出:
同样,由于
the_string
参数是按值传递的,因此为其分配一个新字符串对方法外部的代码看不到任何影响。 Thethe_string
was a copy of theouter_string
reference, and we hadthe_string
point to a new string, but there was no way to change whereouter_string
指出。我希望这可以解决一些问题。
编辑: 有人指出,这并没有回答@David 最初提出的问题,“我可以做些什么来通过实际引用传递变量吗?”。让我们努力吧。
我们如何解决这个问题?
正如@Andrea 的回答所示,您可以返回新值。这不会改变事物传递的方式,但可以让您获得想要退出的信息:
如果你真的想避免使用返回值,你可以创建一个类来保存你的值并将它传递给函数或使用现有的类,比如列表:
虽然这看起来有点麻烦。