Python NoneType对象未按预期工作

时间:2017-03-22 03:13:37

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

我试图pass by object String cmdStr = "C:\\RLX\\VM\\bin\\engine.exe"; Process ps = Runtime.getRuntime().exec(cmdStr); k = ps.exitValue(); 值,希望将其重新分配给实际值。有人可以解释为什么这不起作用吗?我认为,因为NoneNone,它将通过引用传入,当我使用传入的变量时,我会改变原始的NoneType对象。这是不正确的?我在下面提供了一个片段来演示我的案例:

None

结果是class MyClass: def __init__(self): self.value = None def assign(self, object): object = OtherClass() example = MyClass() example.assign(example.value) 仍为example.value。这是为什么?我读了一些SO posts,但没有一个人能够解释这一点。

编辑:不重复,因为我想知道为什么当我认为它应该通过引用传递时它的行为类似于传递值。最后,我得出结论 None对象是不可变的因此总是按值传递。我需要使用NoneType类型的对象或可变的东西。

再次编辑:我的示例代码只是一般情况。我试图实现BST,我的初始根节点是list,当我将根节点指定为None对象时,它仍然是Node,这导致我成为困惑,是这个问题的原因。

最后编辑:下面的回答提供了一个非常好的tl; dr传递对象的摘要。我无法通过搜索/阅读论坛来理解。

2 个答案:

答案 0 :(得分:2)

这恰恰是对象调用(Python规则)与按引用调用(C ++引用语义)不同的情况。

不同之处在于,分配一个非限定名称会重新绑定名称,它对以前可能绑定的名称没有任何影响(除非可能会破坏它,如果没有其他引用仍然存在)。该名称与可能引用同一对象的任何其他名称没有任何关联,因此其他名称不会更改。

因此,在这种情况下,object最初设置为指向相同的对象example.value。但是在下一行,你重新绑定object(非限定名称赋值),它指向一个完全不同的对象。

相比之下,如果你有:

def assign_value(self, object):
    object.value = OtherClass()

并用:

调用它
example.assign(example)

然后exampleobject将引用同一个对象,您对限定名称的分配将替换该一个对象上的value

所有这一切,你的用例在这里不需要任何这样的改变。调用example.assign(example.value)没有任何意义,因为self是隐式传递的,并且可以让您自动访问value(合格访问权限)。看起来像你真正想要的只是在没有参数的情况下请求延迟初始化:

def assign(self):
    self.value = OtherClass()

称为:

example.assign()

回复您的修改:Python documents this call behavior explicitly

  

调用函数调用的实际参数(参数)在被调用函数的本地符号表中引入;因此,参数是使用call by value传递的(其中值始终是对象引用,而不是对象的值)。[1]

脚注1澄清:

  

[1]实际上,通过对象引用调用将是一个更好的描述,因为如果传递了一个可变对象,调用者将看到被调用者对其做出的任何更改(插入到列表中的项目)。

这是有意的;当你没有其他可用的调用语义时,C ++引用语义是不可行的,因为没有明显的选择退出方式,这意味着沿着一个巨大的调用链的每个变量最终引用相同的对象,导致大量的动作在a -distance。

答案 1 :(得分:0)

问题是函数调用传递值而不是引用。具体来说,传递给函数的引用保持不变,直到它被反弹(它的值设置),此时在函数的本地创建一个副本。 other = ...形式的任何行都会导致这种情况发生。如果您需要此行为,则需要使用可变对象,例如列表。例如:

class MyClass:
    def __init__(self):
        self.value = [None]

    def assign(self, object):
        object[0] = OtherClass()

example = MyClass()
example.assign(example.value)

希望这有帮助!