代码之家  ›  专栏  ›  技术社区  ›  Pratik Deoghare

python“奇怪”输出

  •  2
  • Pratik Deoghare  · 技术社区  · 14 年前
    class Foo(object):
        def __init__(self,x):
            self.x = x
            self.is_bar = False
        def __repr__(self): return str(self.x)
    
    class Bar(object):
        def __init__(self,l = []):
            self.l = l
        def add(self,o):
            self.l += [o]
        def __repr__(self): return str(self.l)
    
    def foo_plus_foo(f1,f2):
        t = Bar()
        if not (f1.is_bar and f2.is_bar):
            f1.is_bar = True
            f2.is_bar = True
            t.add(f1)
            t.add(f2)
            print 'HERE'
        return t
    
    if __name__ == '__main__':
        li = [Foo(1), Foo(2)]
        print foo_plus_foo(li[0],li[1])
        print foo_plus_foo(li[0],li[1])
    

    意外输出:

    HERE
    [1, 2]
    [1, 2]
    

    预期输出:

    HERE
    [1, 2]
    []
    

    发生什么事了?我做错了什么?为什么python使用旧值?我该怎么做才能避免这种情况?

    谢谢!

    4 回复  |  直到 14 年前
        1
  •  5
  •   S.Lott    14 年前

    def __init__(self,l = []):
    

    list []

    def __init__( self, l= None ):
        if l is None: l = []
    

        2
  •  4
  •   unutbu    14 年前

    l [] 这是一个 classic Python pitfall .

    class Bar(object):
        def __init__(self,l = []):
    

    默认值的计算位置为 定义时间 非运行时。 只评估一次。

    所以 t=Bar() 集合 t.l 每次都在同一个列表中。

    要解决此问题,请将条形图更改为

    class Bar(object):
        def __init__(self,l = None):
            if l is None:
                l=[]
            self.l = l
        def add(self,o):
            self.l += [o]
        def __repr__(self): return str(self.l)
    
        3
  •  1
  •   kevpie    14 年前

    罪魁祸首是 [L]

    class Bar(object):
        def __init__(self,l = []):
            self.l = l
        def add(self,o):
            self.l += [o]
        def __repr__(self): return str(self.l)
    

    class Bar(object):
        def __init__(self,l = None):
            if l is None:
                self.l = []
            else:
                self.l = l
        def add(self,o):
            self.l += [o]
        def __repr__(self): return str(self.l)
    
        4
  •  1
  •   kindall    14 年前

    l=None

    class Bar(object):
        def __init__(self, l=[]):
            self.l = list(l)
            # and so on...
    

    self.l

    list() deepcopy() copy