代码之家  ›  专栏  ›  技术社区  ›  KobeJohn

我做错什么了?Python对象实例化是否保留以前实例化的数据?

  •  5
  • KobeJohn  · 技术社区  · 16 年前

    有人能指出我做错了什么,或者我的理解哪里错了吗?

    在我看来,下面实例化两个对象的代码对于每个实例化应该有单独的数据。

    class Node:
        def __init__(self, data = []):
            self.data = data
    
    def main():
        a = Node()
        a.data.append('a-data') #only append data to the a instance
    
        b = Node() #shouldn't this be empty?
    
        #a data is as expected
        print('number of items in a:', len(a.data))
        for item in a.data:
            print(item)
    
        #b data includes the data from a
        print('number of items in b:', len(b.data))
        for item in b.data:
            print(item)
    
    if __name__ == '__main__':
        main()
    

    >>> 
    number of items in a: 1
    a-data
    number of items in b: 1
    a-data
    
    3 回复  |  直到 16 年前
        1
  •  13
  •   S.Lott    16 年前

    做这个。

    class Node:
        def __init__(self, data = None):
            self.data = data if data is not None else []
    

    创建类定义时,它会创建 []

        2
  •  5
  •   David Z    16 年前

    问题在于:

    def __init__(self, data = []):
    

    data = [] 为了将空列表设置为该参数的默认值,Python只创建一次列表,并且每次调用方法时都使用相同的列表,而不使用显式表达式 data 争论。在你的例子中,这发生在两者的创造中 a b ,因为两个构造函数都没有显式列表,所以 b 使用同一个对象作为 数据

    为了解决这个问题,我建议将构造函数的第一行替换为

    def __init__(self, data=None):
        if data is None:
            data = []
    
        3
  •  2
  •   Wilduck    16 年前

    当为函数或方法提供默认值时,通常需要提供不可变的对象。如果您提供了一个空列表或一个空字典,那么最终将导致对该函数或方法的所有调用共享该对象。

    一个好的解决方法是:

    def __init__(self, data = None):
        if data == None:
            self.data = []
        else:
            self.data = data