0

Python のドキュメントには、キーワード引数 (用語集) について次のように記載されています。

...変数名は、値が割り当てられる関数内のローカル名を指定します...

したがって、明示的に述べられていない限り、クラスの異なるインスタンスは本当に異なると思いました。ただし、次のコードは、クラスの両方のインスタンスの 1 つのメンバー変数を /same/ オブジェクトに参照します。明らかに、指定されたデフォルト値を介して (メソッドのキーワード辞書がクラス変数 (「静的」) であるかのように) 参照します。メンバーを変更するとすべて問題ありませんが、何らかの理由でそれが起こらない場合:

  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()
    

出力:

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
4

1 に答える 1

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

動作するはずです

于 2012-08-09T04:31:06.040 に答える