2011-01-11 4 views
3

私は、次のコードなぜこのクラスメンバーにPythonでアクセスできないのですか?

class Transcription(object): 
    WORD = 0 
    PHONE = 1 
    STATE = 2 

    def __init__(self): 
     self.transcriptions = [] 

    def align_transcription(self,model,target=Transcription.PHONE): 
     pass 

ここで重要な部分は、私は、変数のデフォルト値としてクラスのメンバを持ちたいということですがあります。ただし、次のようなエラーが発生します。

NameError: name 'Transcription' is not defined 

なぜこれができないのですか、このようなことを行うための正しい方法(Pythonic)は何ですか。

+0

正しい方法?あなたは何をしようとしていますか?なぜオブジェクトのクラスをそのオブジェクトの関数に渡すのですか?あなたがここで何をしようとしているのか分かりません。 –

+2

彼は、メソッドパラメータのデフォルト値としてクラスにスコープを持つ定数を使用したいとします。 –

+0

そうです。私の悪い。構文色付けは私を盲目にした。 :) –

答えて

11

defステートメントが実行されているときにTranscriptionが定義されていないため、アクセスできません。

def align_transcription(self,model,target=PHONE): 
     pass 

トリックを行います。 PHONEという名前は、Transcriptionクラスとなる名前空間で利用可能です。classステートメントの実行が終了しました。

この方法は、classが実際に実行される文であることです。です。 Pythonがクラスステートメントを検出すると、新しいローカルスコープに入り、それが関数であるかのようにclassステートメントの下に字下げされたものすべてを実行します。その後、結果の名前空間、クラスの名前、およびベースクリップのタプルがメタクラス(デフォルトではtype)に渡されます。メタクラスは、実際のクラスである自身のインスタンスを返します。これは、defステートメントが実行されたときには発生していません。

声明

class Foo(object): 
    a = 1 
    def foo(self): 
     print self.a 

は、名前空間ns = {'a': 1, 'foo': foo}を作成し、

Foo = type('Foo', (object,), ns) 

これは、あなたがFooを一度に定義されていないことをはっきりと見ることができます

def foo(self): 
    print self.a 

Foo = type('Foo', (object,), {'a': 1, 'foo': foo}) 

と同等であるを実行しますfooが定義されているのでは意味をなさない。

+0

+1は非常に明確な説明です! – EOL

1

align_transcriptionメソッドを定義するとき、トランザクションクラスはまだ存在しませんが、スコープ内でPHONEを使用できます。だから、 、あなたがこの方法のいずれかを行うことができます。

def align_transcription(self,model,target=None): 
    if target is None: 
     target = self.PHONE 
2

クラスは、その名前に関連付けられていないが:あなたはサブクラスまたはインスタンスでPHONEを上書きすることを計画している場合

class Transcription(object): 
    WORD = 0 
    PHONE = 1 
    STATE = 2 

def __init__(self): 
    self.transcriptions = [] 

def align_transcription(self,model,target=PHONE): 
    pass 

またはターゲット=該当なしデフォルトで

定義の終わりまで

私はこれを記述します(と私はそれがPython的だと保証することはできません)方法は次のとおりです。

また
class Transcription(object): 
    WORD = 1 # zero won't work below... need to change the value 
    PHONE = 2 
    STATE = 3 

    def align_transcription(self, model, target=None): 
     target = target or Transcription.PHONE 
     # or 
     if target is None: target = Transcription.PHONE 

、ゼロの代わりに、WORDからPHONEは罰金になります設定。ifステートメントは定数の値に関係なく動作しますが、orは0の値をPHONEに置き換えます。

他のオプション他のクラスの定数を定義したり、クラスの外でalign_transcription方法をバインドするために、次のとおりです。

class Transcription(object): 
    WORD = 0 
    PHONE = 1 
    STATE = 2 

def _unbound_align_transcription(self, model, target=Transcription.PHONE): 
    pass 

Transcription.align_transcription = _unbound_align_transcription 
+1

またはhttp://stackoverflow.com/questions/4655745/why-can-i-not-access-this-class-member-in-python/4655770#4655770のようにする...私はそれを知っていた、ただdidnすぐにそれを考えないでください。 – Zooba

+0

私は、 "そのクラスオブジェクトは定義が完了するまで利用できません"という単純なレスポンスを考えると –

+0

これは真ですが、クラス内で定義されている値を除いて利用可能です。 'def'行)は、定義されたポイントでクラススコープにあり、バインドされた関数* code *はそうではないので、クラス名を使用して曖昧さを除去する必要があります。 – Zooba

関連する問題