2012-04-30 5 views
1

何が間違っていますか?私はクラスに精通していないクラスラムダコールバックNameError

class monitor(): 
    def update(self): 
     print "Called" 

    mon = Tk() 
    mainFrame = Frame(mon) 
    mainFrame.grid(row=1, column=1) 

    optionFrame = Frame(mainFrame) 
    optionFrame.grid(row=1, column=1) 

    refreshB = ttk.Button(optionFrame, text='Refresh', command=lambda: update('self')) 
    refreshB.grid(row=1, column=1) 

    mon.mainloop() 

monitor() 


**NameError: global name 'update' is not defined** 

私は「refreshB」ボタンをDEF「更新」を呼びたいが、私は代わりにnameErrorを取得し、私は追加することが出来るのです何か他のものはありますか?スクリプトが上記のクラスでなかった場合

その後、私が使用します。希望が正常に動作します

refreshB = ttk.Button(optionFrame, text='Refresh', command=lambda: update) 

...

+0

あなたは関数としてクラス構造を扱っています。彼らは同じことではありません。クラスを呼び出すと、クラス内のコードは実行されません。代わりに、クラスで定義された '__init__'メソッドを呼び出し、クラスの新しいインスタンスを返します。 –

答えて

1

置き、すべての初期化コードを初期化関数の内部で。次にupdate()self.update()としてください。それはinstancemethodではなくクラスメソッドだから

class Monitor(object): 
     def update(self, event): 
      print "Called" 

     def __init__(self): 
      self.mon = Tk() 
      self.mainFrame = Frame(self.mon) 
      self.mainFrame.grid(row=1, column=1) 

      self.optionFrame = Frame(self.mainFrame) 
      self.optionFrame.grid(row=1, column=1) 

      self.refreshB = ttk.Button(self.optionFrame, text='Refresh', command=self.update) 
      self.refreshB.grid(row=1, column=1) 

     def run(self): 
      self.mon.mainloop() 

    monitor = Monitor() 
    monitor.run() 

update()参照は、ここでは動作しません。なぜラムダ関数を使用する必要があるのか​​わかりませんが、ラムダの使用のためではありません。私の解決策は、Monitorのインスタンスを作成することです。これは、Monitor内のコードがいつ実行されるかを制御できるので便利です。 (それ以外の場合は、クラス本体のコードが定義時に実行されます。monitor()を呼び出すと、クラスmonitorのインスタンスが返されます) - コード本体を実行しません。

+0

ああ、それをクリアしてくれてありがとう。私はまだPythonにはまったく新しく、3ヵ月ほどしか使用していません。ラムダを使ってオブジェクトをdefに渡すことができました。過去に私のために働いていましたが、クラスの使い方を学んでいます。もう一度あなたの助けと時間をありがとう:) – user1159817

0

コードは実際にはありませんそれはクラス内で直接的な副作用があります。あなたはほぼ確実にすべてのことのコードは、あなたのmonitorオブジェクトが作成された後に呼び出される代わりに__init__機能、になりたい:

def __init__(self): 
    mon = Tk() 
    etc... 

次に、updateには、オブジェクトに対して呼び出す必要がありますので、インスタンスメソッドです。最後に、lambdaは無用である

refreshB = ttk.Button(optionFrame, text='Refresh', command=lambda: self.update()) 

:あなたはおそらくこれ欲しい:

refreshB = ttk.Button(optionFrame, text='Refresh', command=lambda: self.update('self')) 

しかし、あなたのupdate方法は暗黙のself引数を超えた任意の引数を取りませんので、その後、あなたは実際には、おそらくこれが欲しいです間接。 lambdaにラップするのではなく、コールバックとして直接メソッドを渡すのはなぜですか?

refreshB = ttk.Button(optionFrame, text='Refresh', command=self.update) 
+0

ああ、あなたも正しいです。私は引数を渡すためにラムダを使用しています、私はちょうど私のサンプルコードにそれを含めることを忘れました。しかし、あなたの説明はとても役に立ちます。私もあなたにチェックマークを付けることができたら、私はそうするでしょう。 – user1159817