2016-12-07 15 views
1

実行時にクラスに新しいプロパティを設定しようとしていて、特定のプロパティ固有のデータに依存するラムダを付けようとしています。クラスBのようにループ内でプロパティを設定すると、最初のプロパティが上書きされます。それらを順番に設定している間、問題を見つけることができません。他の質問には、linkのように、プロパティの代わりに__getattr__を使用する必要があるという記述があります。しかし、私はここで何が問題なのか理解したいと思います。ループ内のクラスにプロパティを設定すると、最後のプロパティが上書きされます

import time 
class A(): 
    def __init__(self, dynprops = ['a', 'b']): 

     setattr(A, 'a', property(lambda x: self.print_prop('a'))) 
     setattr(A, 'b', property(lambda x: self.print_prop('b'))) 

    def print_prop(self, dynprop): 
     print(time.time(), dynprop) 

class B(): 
    def __init__(self, dynprops = ['a', 'b']): 

     for prop in dynprops: 
      setattr(B, prop, property(lambda x: self.print_prop(prop))) 

    def print_prop(self, dynprop): 
     print(time.time(), dynprop) 

a = A() 
print(a.a) 
print(a.b) 
b = B() 
print(b.a) 
print(b.b) 

それはpropが 'B' に変更されているので起こり、その後、そのようにとどまる

>> 1481137121.6755576 a 
>> None 
>> 1481137121.6756482 b 
>> None 
>> 1481137121.6757774 b 
>> None 
>> 1481137121.6758344 b 
>> None 

答えて

3

を与えます。 lambda関数は、lambdaの作成時に割り当てられた値ではなく、現在の値propを返します。この現象を回避するには、クロージャを使用する必要があります。

class B(): 
    def __init__(self, dynprops = ['a', 'b']): 
     for prop in dynprops: 
      setattr(B, prop, property(self.printer(prop))) 

    def print_prop(self, dynprop): 
     print(time.time(), dynprop) 

    def printer(self, prop): 
     return lambda x: self.print_prop(prop) 
関連する問題