2010-11-20 15 views
6

メソッドをクラスに追加する関数を作成するにはどうすればよいですか?私は持っています:Pythonメタプログラミング:メンバー関数を自動的に生成する

class A: 
    def method(self): 
     def add_member(name): 
      self.new_method = def name...? 

     add_member("f1") 
     add_member("f2") 

私がしようとしていることに答えるためです。私はいくつかのpyqtスロットを除外しようとしています。私は、QSliderQLabelを作成し、スライダ処理コードを作成し、sliderハンドラがQLabelのテキストを更新するように、関数create_sliderを呼び出せます。ここで因数分解する必要があるスロットがあります:

def on_sample_slider(self, value): 
     self.samples = pow(4, value) 
     self.sample_label.setText('%d' % self.samples) 

ここにいくつかのUIを生成する方法だが、また、on_sample_slider方法にそれが呼び出されるたびに発生しているといいだろう。

def insert_labeled_slider(hbox, name, slider_target): 
     # name 
     hbox.addWidget(QLabel(name)) 

     # label 
     label = QLabel() 
     label.setMinimumSize(40, 0) 
     hbox.addWidget(self.sample_label) 

     #slider 
     slider = QSlider(Qt.Horizontal) 
     slider.setRange(0, 6) 
     slider.setTracking(True) 
     slider.setPageStep(1) 
     hbox.addWidget(slider) 

     self.connect(self.sample_slider, SIGNAL('valueChanged(int)'), 
        self.on_sample_slider) 
     self.sample_slider.setValue(0) 
     return (label, slider) 

最終コード:

def attach_on_slider(obj, name, variable, label, base): 
    def on_slider(self, value): 
     variable = base**value 
     label.setText('%d' % variable) 

    # This next line creates a method from the function 
    # The first arg is the function and the second arg is the object 
    # upon which you want it to be a method. 
    method = types.MethodType(on_slider, obj) 
    obj.__dict__["on_slider_" + name] = method 
    return method 

class A: 
    def insert_labeled_slider(hbox, name, label_name, variable): 
     # name 
     hbox.addWidget(QLabel(label_name)) 

     # label 
     label = QLabel() 
     label.setMinimumSize(40, 0) 
     hbox.addWidget(label) 

     #slider 
     slider = QSlider(Qt.Horizontal) 
     slider.setRange(0, 6) 
     slider.setTracking(True) 
     slider.setPageStep(1) 
     hbox.addWidget(slider) 

     on_slider_method = attach_on_slider(self, name, variable, label, 4) 

     self.connect(slider, SIGNAL('valueChanged(int)'), 
        on_slider_method) 
     slider.setValue(0) 
     return (label, slider) 
+1

メソッドf1とf2は既にどこかで定義されていますか? – BudgieInWA

+0

いいえ、私はヘルパー関数内でそれらを生成しようとしています。 –

+0

(私はいくつかの同じメンバ関数を除外しようとしています。) –

答えて

7

ここに新しく投稿コードから実際の例です:

import types 

def attach_on_sample_slider(obj, base): 
    def on_sample_slider(self, value): 
     self.samples = base**value 
     self.sample_label.setText('%d' % self.samples) 

    # This next line creates a method from the function 
    # The first arg is the function and the second arg is the object 
    # upon which you want it to be a method. 
    obj.on_sample_slider = types.MethodType(on_sample_slider, obj) 

あなたは今、あなたはメンバ関数が同一であると言うので、私はそれをこの

def make_method(name): 
    def method(self, whatever, args, go, here): 
     #whatever code goes here 
    method.__name__ = name 
    return method 


class A(object): 
    method1 = make_method('method1') 
    method2 = make_method('method2') 
ような何かをするだろう

def some_method(self, foo): 
    attach_on_sample_slider(self, 4) 

のようなオリジナルのポストを呼び出すことができます

厳密に言えば、名前を渡して新しい関数の属性は必要ではありませんが、デバッグに役立ちます。それは少し重複し、それ自体のために支払うことができます。あなたもそれをスキップする場合は、同様に行う可能性があります。

class A(object): 
    def method1(self, arg1, arg2): 
     #code goes here 

    method2 = method1 
    method3 = method1 

これは同じメソッドを作成します。どちらかを呼び出すと、同じメソッドが生成されます。

名前の他の引数をmake_methodに渡して、返されたメソッドの異なるバージョンでそれらのパラメータがクロージャーにアクセスして別々に動作するようにすることができるため、最初の形式はより強力です。ここでの機能を持つ愚かな例は、(メソッドと同じ動作します)です。ここで

def make_opener(filename): 
    def opener(): 
     return open(filename) 
    return opener 

open_config = make_opener('config.cfg') 
open_log = make_opener('log.log') 

、彼らがして作成されたfilenameの値へのアクセスを持っているので、彼らはすべて本質的に同じ機能だが、わずかに異なることを行います。あなたがこのようなことをたくさんしているのであれば、クロージャーは間違いなく目を引くものです。

これ以上のことがありますので、特に問題がある場合は、質問を更新する必要があります。

+0

これは全く驚くべきことですが、私がC++の代わりにPythonを使用している理由の1つです。 –

+0

私はあなたがクラスの主なスコープでメソッドを作っていることに気付きました。クラスのメンバ関数でメソッドを作成し、その時にバインドできますか?例えば、 'self.method1 = make_method ...'と書くことによって? –

+0

うわー、あなたがPythonでそれをすることができるのか分からなかった! – helpermethod

関連する問題