我正在尝试pass by object一个None
值,希望将其重新分配给实际值。有人能解释一下为什么这不起作用吗?我想既然None
是一个NoneType
,那么它将通过引用传入,当我使用传入变量时,我会改变原来的None
对象。这不正确吗?我在下面提供了一个片段来演示我的案例:
class MyClass:
def __init__(self):
self.value = None
def assign(self, object):
object = OtherClass()
example = MyClass()
example.assign(example.value)
结果是example.value
仍然是None
。为什么?我读过一些SO posts,但没有一个清楚地解释这一点。在
编辑:不是重复的,因为我想知道为什么当我认为它应该是按引用传递时,它的行为像传递值一样。最后,我得出结论,NoneType
对象是不可变的,因此总是按值传递。我需要使用list
类型的对象或可变的对象。在
再次编辑:我的示例代码只是一般情况。我试图实现一个BST,我的初始根节点是None
,当我将根节点指定为Node
对象时,它仍然是NoneType
,这让我很困惑,这也是这个问题的原因。在
最后编辑:下面的答案提供了一个非常好的传递对象的tl;dr摘要。我只是通过搜索/阅读论坛无法理解。在
问题是函数调用传递值,而不是引用。具体地说,传递给函数的引用保持不变,直到它反弹(它的值集),此时在函数的本地创建一个副本。任何形式的
other = ...
都会导致这种情况发生。如果你想要这种行为,你需要使用一个可变的对象,比如一个列表。例如:希望这有帮助!在
这正是对象调用(Python规则)不同于引用引用(C++引用语义)的情况。在
不同的是,分配给一个不合格的名称会重新绑定该名称,它对该名称以前可能绑定的任何内容都没有任何影响(除了可能销毁它之外,如果没有其他引用的话)。该名称与可能引用同一对象的任何其他名称没有连接,因此这些其他名称不会更改。在
所以在本例中,
object
最初被设置为指向example.value
指向的同一对象。但是在下一行中,重新绑定object
(非限定名称赋值),它指向一个完全不同的对象。在相比之下,如果你有:
并称之为:
^{pr2}$那么}将引用同一个对象,并且您对限定名的赋值将替换该对象上的
example
和{value
。在尽管如此,这里的用例不需要任何这样的更改。调用
example.assign(example.value)
没有任何意义,因为self
是隐式传递的,它将自动授予您对value
的访问权(限定访问权)。似乎您真正想要的只是在请求时延迟初始化,而没有任何参数:称为:
针对您的编辑:Pythondocuments this call behavior explicitly:
其中脚注1阐明:
<>这是有意的;当你没有其他调用语义时,C++引用语义是不可行的,因为没有明显的选择方法,意味着沿着一个巨大的调用链的每个变量都结束引用同一个对象,导致大量的行动距离。在相关问题 更多 >
编程相关推荐