附加函数将元素添加到列表成员

Posted

技术标签:

【中文标题】附加函数将元素添加到列表成员【英文标题】:Append function adds element to member of list 【发布时间】:2020-12-19 04:41:24 【问题描述】:

如何在不修改其成员的情况下将 Class 对象附加到列表中?

class Node:
    def __init__(self, name, type, children=[]):
        self.name = name
        self.type = type
        self.children = children

    def add_child(self, child_node):
        self.children.append(child_node)

    def printNode(self, indent = 0):
        print(self.name + " has children " + str(len(self.children)))
        #for child in self.children: print(child, indent + 4)
            
if __name__ == "__main__":
    A = Node("A", "company")
    B = Node("B", "department")
    B.printNode()
    A.add_child(B)
    B.printNode()

append() 函数将节点 B 添加到自身,即使它应该只将其添加到节点 A 的子列表中,从输出中可以看出

B has children 0
B has children 1

【问题讨论】:

【参考方案1】:

在 Python 中为函数定义参数时,您偶然发现了一个非常常见的问题。有一个很好的解释here。

当您定义一个函数时,Python 解释器将创建用作默认参数的值。然后将这些默认值用于每个函数调用。在这种情况下,在解释 __init__ 时会创建空列表 children=[]。然后每次调用add_child() 时都会使用同一个列表,无论调用哪个对象。

这是一个例子:

def my_func(a_list=[]):
    a_list.append("something")
    print(a_list)

>>> my_func()
["something"]
>>> my_func()
["something", "something"]

在这种情况下,a_list 会在每个函数调用中重复使用,并且会继续增长。

解决这个问题的方法是使用不同的值来表示节点应该从一个空的子列表开始。像这样:

class Node:
    def __init__(self, name, type, children=None):
        self.name = name
        self.type = type
        self.children = children or []

...

【讨论】:

【参考方案2】:

永远不要使用可变数据(例如列表)作为默认参数。像这样重新定义您的构造函数,它将按预期工作

def __init__(self, name, type, children=None):
    self.name = name
    self.type = type
    self.children = children if children else []

【讨论】:

阅读更多 here 和 here

以上是关于附加函数将元素添加到列表成员的主要内容,如果未能解决你的问题,请参考以下文章

iOS - 将元素附加到领域中的列表不会保留元素

是否可以将元素附加到 JavaScript 节点列表?

在列表中添加元素

如何在不跟踪索引的情况下将元素附加到列表?

附加到 Python 中的列表:每次都添加最后一个元素?

PHP:通过 ID 将 html 内容附加(添加)到现有元素