2011-12-14 6 views
5

クラスに関するいくつかの情報をクラス(静的)変数として保存したいと思います。しかし、私はこれらのものがどのように初期化されるか把握できません。Pythonクラス変数の初期化

class A(object): 
    clsVar = 'a' 
    @classmethod 
    def clsMeth(cls): 
     print 'changing clsVar' 
     cls.clsVar = 'b' 
    A.clsMeth() 
# prints 'changing clsVar' 

print A.clsVar # prints 'a' 
A.clsVar = 'b' 
print A.clsVar # prints 'b' 

関数が呼び出された(printステートメントが働いたので)、なぜクラス変数は変更されませんでしたか?クラス定義の完了後にメタクラスを使用したくない場合は、メタクラスを使用する必要がありますか?

[具体的には、私はclsMethをデコレータにして、class変数をそのように装飾されたすべての関数のリストにします。私はこれを達成するための正しい方法ではないと推測しているので、私は移動しましたが、私はまだ興味があります。]

EDIT:上記のコードは、実行する。私はA.clsMeth()への呼び出しがAの前のバージョンを参照し、実行するIPythonセッションで実行していました。そのようなことは、通訳された言語を使用するリスクです。私はこのようなものと一緒に行くことになった:

outsideDict = {} 
def outsideDec(func): 
    outsideDict[func.__name__] = func 

class A(object): 
    @outsideDec 
    def someMethod(self): 
     print 'ID %s' % id(self) 

    def otherMethod(self): 
     print 'other' 

print outsideDict 
one, two = A(), A() 
outsideDict['someMethod'](one) 
outsideDict['someMethod'](two) 

は、おそらくこれは、別の質問をする必要がありますが、outsideDecが実行されますと、それは引数がメンバーである何クラス伝える方法はありますか?あるいは、Pythonでこのようなイントロスペクションを行う良い方法がありますか?私はここでコースを外れていると認識していますので、私は以下の答えを受け入れ、より多くの研究をします。みんな、ありがとう!

+0

「A」が定義されていないため、「A.clsMeth」を呼び出すときにエラーが発生します。多分あなたは通訳を使っていて、あなたは古い 'A'定義を持っていますか? – jcollado

+0

このサンプルをどのように実行しますか?構文が正しくないため、これは機能しません。 'A.clsMth()'はこのようにクラス定義の中に置くことはできません。 – gecco

+0

@gecco:可能です。構文は問題ありません。 'Acl 'への代入は' A.clsMeth() 'が呼び出されたときに行われていないので、実行時エラーで失敗します。 –

答えて

4

Aとして実行されませんAの定義におけるA.clsMeth()への呼び出しは、その時点で存在しません:

A(例えば、もし以前に定義されていた場合、コードが動作するように見えたかもしれない

>>> class A(object): 
...  clsVar = 'a' 
...  @classmethod 
...  def clsMeth(cls): 
...   print 'changing clsVar' 
...   cls.clsVar = 'b' 
...  A.clsMeth() 
... 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 7, in A 
NameError: name 'A' is not defined 
あなたはREPLでそれをテストしていました)、 A.clsMethへの呼び出しは古いクラスで呼び出されていました。これは新しいクラスによって隠されていました。 「もちろん

>>> class A(object): 
...  clsVar = 'a' 
...  @classmethod 
...  def clsMeth(cls): 
...   print 'changing clsVar' 
...   cls.clsVar = 'b' 
... 
>>> A.clsMeth() 
changing clsVar 
>>> A.clsVar 
'b' 

、fabianhrjが述べたように、あなたにも、コンストラクタにそれを置くことができますが、それは勝った:

しかし、我々は間違いなく定義した後、そのコールを入れて、あなたが望む結果を得ることができますインスタンスを作成するまでは呼び出されません。

0

すべてのステートメントを機能させる必要があります。オブジェクトが作成されたときに何かを実行したいのであれば、それをコンストラクタに入れておくことをお勧めします。

class A: 
    def clsMeth(self): 
     print("Changing clsVar") 
     self.clsVar = 'b' 
    def __init__(self): 
     self.clsMeth() 
    clsVar = 'a' 

あります。

+0

'__new__'または' __init__'を意味しますか? – kennytm

+0

はい、コンテキストをPythonに切り替えることができます。 –

+0

OKを修正しました。あなたは確認できますか? –