为什么python不允许通过引用传递变量

时间:2013-08-20 06:26:54

标签: python pass-by-reference python-nonlocal

这可能更适合讨论组,但我并不精通 语言的内在(甚至是语言本身)。无论如何,困扰我的是:

如果python允许使用nonlocal关键字对外部作用域进行干扰(副作用),那么为什么它不允许对函数参数进行类似的干扰 允许通过引用传递参数:

现在可能:

>>> def outer():
       x = 1
       def inner():
           nonlocal x
           x = 2
           print("inner:", x)
       inner()
       print("outer:", x)

>>> outer()
inner: 2
outer: 2

为什么不 - 或者如果我们有什么可能出错:

>>> def outer():
       x = 1
       def inner(byref x):
           x = 2
           print("inner:", x)
       inner(x)
       print("outer:", x)

>>> outer()
inner: 2
outer: 2

(使用某些关键字,例如'byref'或'nonlocal,仅用于说明)。

4 个答案:

答案 0 :(得分:2)

Python总是使用参考值传递参数。请参阅此处的this链接,特别是用户提供的详细回复 pepr

同样this链接有关于如何在python中传递参数的确切详细讨论,并且还可以模拟 pass-by-reference - 请参阅对此接受的答案的编辑问题

如果您希望深入研究 - 请参阅此Effbot文章,该文章还包含围绕同一主题的一些辩论/讨论。

答案 1 :(得分:1)

这是不可能的,因为Python根本没有“变量”的概念。 Python程序中的所有名称都是对象的引用。因此,在调用函数或方法时,只能传递对象的引用。这称为通过参考值传递。

但是,无法获得对现有参考的引用。在这方面,引用是Python世界中唯一的“非一流”公民。

程序中的名称引用了两种对象:immutable(例如string,int,tuple)是一个可变的(例如list,set,大多数用户类)。

您可以在可变对象上调用实际上修改对象状态的方法,这看起来类似于使用C ++等语言传递对象的引用。除此之外,通过引用传递在Python中没有多大意义。

请参阅Prahalad Deshpande对某些链接的回答。

答案 2 :(得分:1)

假设您允许引用参数。那么,当您执行以下操作时会发生什么?

def f(byref x):
    print x
    print x
    x = 3

class Foo(object):
    def __init__(self):
        self.count = 0
    @property
    def x(self):
        count += 1
        return count

f(Foo().x)

什么时候叫getter?它叫多少次?这会打印1两次,还是打印1,然后是2,或2,然后是3?由于没有setter,当你尝试分配给x时会发生什么?

在另一种语言中,变量是放置东西而不是值的名称的地方,这不是问题。 Foo().x一旦评估就会有一个内存位置,而f会将该内存位置用于其x参数。在Python中,它不像那样工作。您无法传递1的内存位置并更改其内容,因为其他代码会突然发现1神奇地2。 Python的名称语义和属性/项getter / setter使得引用参数比C ++这样的语言更令人困惑,因为它们已经让人感到困惑和容易出错。

答案 3 :(得分:0)

在Python int中,对象是不可变的。当您认为自己正在更改x的值时,您实际上是在不同的内存位置创建新的int并让x引用它。