通过方法定义中的参数默认值引用同一对象的不同类实例的成员

时间:2012-08-09 04:28:00

标签: python class static multiple-instances keyword-argument

Python文档说明关键字参数(词汇表):

  

...变量名称指定赋值的函数中的本地名称...

因此,除非另有说明,否则我认为一个班级的不同实例是真正不同的 明确。然而,以下代码引用了两个实例的一个成员变量 类似于/ same / object,显然是通过给定的默认值(就好像是 该方法的关键字字典是一个类变量(“static”))。一旦修改了 会员一切都很好,但如果由于某种原因不会发生:

  1. 我想知道代码的行为是否有充分的理由, 因为它不是我所期望的(见代码和输出中的标记)和
  2. 是否有解决问题的好方法(除了使用'复制')。 感谢。

    class C:
        def setParams(self):
            self.e = []
        def setParamsKw(self, kw=['default list']): # <----- kw arg.
            self.eKw = kw                           # <--- that member should
                                                    #      default to the
                                                    #      default argument
                                                    #      (use 'kw.copy()'?)
    
    def outputMember():
        print " c1.e=", c1.e
        print " c2.e=", c2.e
        print " type(c1.e)=", type(c1.e)
        print " type(c2.e)=", type(c2.e)
        print " c1.e == c2.e:", c1.e == c2.e
        print " c1.e is c2.e:", c1.e is c2.e
    
    def outputMemberKw():
        print " c1.eKw=", c1.eKw
        print " c2.eKw=", c2.eKw
        print " type(c1.eKw)=", type(c1.eKw)
        print " type(c2.eKw)=", type(c2.eKw)
        print " c1.eKw == c2.eKw:", c1.eKw == c2.eKw
        print " c1.eKw is c2.eKw:", c1.eKw is c2.eKw # <----- this result
                                                     #      is unexpected
    
    
    c1 = C()
    c2 = C()
    
    print " c1 == c2:",  c1 == c2
    print " c1 is c2:",  c1 is c2
    
    print "Calling setParams for both instances:"
    c1.setParams()
    c2.setParams()
    outputMember()
    
    print "Calling setParamsKw for both instances:"
    c1.setParamsKw()
    c2.setParamsKw()
    outputMemberKw()
    
    print "Now manually modifying members of c1:"
    c1.e = [1, 2, 3, 4, 5]
    c1.eKw = [1, 2, 3, 4, 5]
    print "e:"
    outputMember()
    print "eKw:"
    outputMemberKw()
    
  3. 输出:

    c1 == c2: False
     c1 is c2: False
    Calling setParams for both instances:
     c1.e= []
     c2.e= []
     type(c1.e)= <type 'list'>
     type(c2.e)= <type 'list'>
     c1.e == c2.e: True
     c1.e is c2.e: False
    Calling setParamsKw for both instances:
     c1.eKw= ['default list']
     c2.eKw= ['default list']
     type(c1.eKw)= <type 'list'>
     type(c2.eKw)= <type 'list'>
     c1.eKw == c2.eKw: True
     c1.eKw is c2.eKw: True
    Now manually modifying members of c1:
    e:
     c1.e= [1, 2, 3, 4, 5]
     c2.e= []
     type(c1.e)= <type 'list'>
     type(c2.e)= <type 'list'>
     c1.e == c2.e: False
     c1.e is c2.e: False
    eKw:
     c1.eKw= [1, 2, 3, 4, 5]
     c2.eKw= ['default list']
     type(c1.eKw)= <type 'list'>
     type(c2.eKw)= <type 'list'>
     c1.eKw == c2.eKw: False
     c1.eKw is c2.eKw: False
    

1 个答案:

答案 0 :(得分:0)

def setParamsKw(self, kw=None): # <----- kw arg.
            self.eKw = kw  if kw == None else ['default list']

应该有效