繁体   English   中英

Python传递对象引用值

[英]Python pass by object reference value

我正在尝试在python中编写一个算法来打印从(二进制)树的根到每个叶子的所有路径。 这是我的代码:

def fb_problem(node, curr_trav):
    curr_trav = curr_trav + [node]

    if node.left is None and node.right is None:
        for path_node in curr_trav:
            print path_node.data 
        print "XXX"

    if node.left is not None:
        fb_problem(node.left, curr_trav)
    if node.right is not None:
        fb_problem(node.right, curr_trav)

fb_problem(root, [])

我在当前遍历中保留了一个节点列表,当我到达一个叶子时,我打印出列表。 我误解了python传递对象的方式。 认为当每个递归调用完成并从堆栈中弹出时,原始的curr_trav变量不会受递归调用的影响。 但是,似乎就行了

curr_trav += [node]

正在改变原始列表。 +=运算符返回一个新列表,而不是.append() ,它实际上会改变原始对象。 所以这个调用不应该只是重新分配给函数中的对象的名称,而不是改变原始对象? 当我改变线条时

t_trav = curr_trav += [node]

一切正常,但我不明白原始线的问题是什么。 如果我的问题不清楚,请告诉我。

使用python它既不是值也不是引用。 它是两者的组合,并且取决于传递给函数的对象的类型。 例如,如果传递了诸如dict, list etc可变类型dict, list etc它将传递引用。 而对于诸如str的不可变类型,它将是值。 关于这个主题的好读物是Jeff Knupp

原始代码curr_trav += [node]的问题在于它将[node]的值添加到curr_trav并将引用设置为新列表。 因为它传递了curr_trav的引用,所以它将在每次后续迭代中更改。

你对+=理解不太正确。 Python中的所有运算符都只是快捷方式。 例如,如果a具有__add__方法,则a + ba.__add__(b) 如果a没有,则为b.__radd__(a) 如果b没有该方法,则会引发错误。 通常, a += b行为与a = a + b非常相似,但在可变对象的情况下,它通常不会。 这是因为如果a具有__iadd__方法,则a += ba.__iadd__(b) 如果a没有,则与a = a.__add__(b) 如果a也没有,则与a = b.__radd__(a) 由于名单确实__iadd__方法,实际列表对象发生变化,而不是重新定义curr_trav

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM