1

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

如果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

4 回答 4

2

Python 总是使用参考值传递参数。请在此处参考链接,尤其是 rad 用户pepr提供的详细回复

此外,此链接还非常详细地讨论了如何在 python 中准确地传递参数,并且还可以模拟传递引用- 请参阅该问题已接受答案的编辑。

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

于 2013-08-20T06:53:48.617 回答
1

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

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

程序中有两种由名称引用的对象:不可变的(例如字符串、整数、元组)和可变的(例如列表、集合、大多数用户类)。

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

有关某些链接,请参阅 Prahalad Deshpande 的答案。

于 2013-08-20T07:23:06.153 回答
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)

什么时候调用吸气剂?它被调用了多少次?这会打印1两次,还是打印1, then22, then 3?由于没有 setter,当您尝试分配 to 时会发生什么x

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

于 2013-08-20T07:57:16.217 回答
0

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

于 2013-08-20T06:36:24.810 回答