2016-03-21 11 views
-1

I次のPythonコードを持っている:Pythonは属性値

#!/usr/bin/python 

def f(x): 
    f.counter = getattr(f, "counter", 0) 
    print("Bfore: ",f.counter) 
    f.counter += 1 
    print("After: ",f.counter) 
    return "pass" 


for i in range(5): 
    f(i) 

私は上記のコードを実行すると、私は次の結果を参照してください。私は期待していた

('Bfore: ', 0) 
('After: ', 1) 
('Bfore: ', 1) 
('After: ', 2) 
('Bfore: ', 2) 
('After: ', 3) 
('Bfore: ', 3) 
('After: ', 4) 
('Bfore: ', 4) 
('After: ', 5) 

を:

f.counter = getattr(f, "counter", 0) 

を呼び出すたびに常に0に初期化されます。

for 

ループで10

f(i) 

。しかし、それはそうではないようです。どうして?

ありがとうございました。

+0

Python 2を使用していますが、Python 3を使用することを示唆しています。Windowsの場合はPython 3を、* nixの場合は 'python3'をインストールしてください。 –

+1

あなたはそれをなぜ期待しましたか?どこで/いつそれが初期化されると思いましたか? 'f'は常に同じ関数オブジェクトを参照しています。もしそれをゼロにリセットしたいのであれば、手動で行う必要があります。 'for i in range(5):f.counter = 0; f(i) 'とする。 – jonrsharpe

答えて

0

fは、常に同じ関数オブジェクトを参照します。

f.counter = getattr(f, "counter", 0)は、f.counterの値をf.counterの現在の値または属性が存在しない場合は0に設定します。

1

f.counter = getattr(f, "counter", 0)は、存在しない場合にのみ0に設定されます。

f.counter = 0 
0

すべてがオブジェクトであることを覚えておいてください。したがって、def f(...)を実行している間は、関数の新しいインスタンスを作成するだけです。あなたは次のように入力して、自分自身を納得させることができます。

def f(foo): 
    print foo 

type(f) # return <type 'function'> 

ここf最初の行でインスタンス化されています。したがって、あなたの例では、常に同じfインスタンスで作業しています。最初の呼び出しでは、counter属性を追加します。 2回目以降の呼び出しでは、同じインスタンスで作業しているので、counter属性はまだ存在します。