2013-05-22 3 views
5

私は良いデザインがあるのか​​どうかは分かりませんが、unittest.TestCaseから派生したクラスがあります。それを設定したら、私のコードはunittestを実行する前に、test_*メソッドをクラスに動的に注入します。私はこれにsetattrを使用します。これはうまくいっていますが、私は前に注入したメソッドを削除し、新しいメソッドセットを注入したいという状況があります。名前がパターンtest_*と一致するクラスのすべてのメソッドを削除するにはどうすればよいですか?Python - クラスからメソッドを動的に削除するにはどうすればいいですか?つまり、setattrの反対側です。

答えて

14

delattrといい、hereと記載されています。

+0

「デル」でも動作しませんか? –

+0

@ JasonSperske:名前がプログラムによって計算される属性を削除する必要がない場合あなたは文字通りソースコードに入力できる名前を削除するのに 'del'だけ使うことができます。 – BrenBarn

+0

@JasonSperske - タイトルは "setattrの反対"と言っています。OPはメソッド名を文字列として認識しています... – mgilson

3
>>> class Foo: 
    def func(self): 
     pass 
...  
>>> dir(Foo) 
['__doc__', '__module__', 'func'] 
>>> del Foo.func 
>>> dir(Foo) 
['__doc__', '__module__'] 
1

delattr()です。クラスのvars()をループし、"test_"で始まる属性名をテストします。例えば、

@classmethod 
def remove_test_methods(cls): 
    for name in list(vars(cls)): 
     if name.startswith("test_") and callable(getattr(cls, name)): 
      delattr(cls, name) 

は、私はあなたがターゲットとしているクラスに定義されてdir()から取得するすべての名前を、これは同様にあなたの親クラスからの名前が表示されますよう、dir()を使用しないことをお勧めし、そうではないと思います。前回の回答に加えとして

+0

これはうまく見えますが、私は 'RuntimeError:iteration中に辞書のサイズを変更しました.' – jononomo

+0

ああ、' vars() 'は辞書を使用しています。私はそれを修正しましょう... – kindall

+0

'dir(cls)' maybe? – thkang

0

:削除するメソッドが再実装されている場合は、サブクラスと親クラスのメソッドを削除する必要があるだろう、両方:

class A: 
    def method(self): 
     print("TestA") 

class B(A): 
    def method(self): 
     A.method(self) 
     print("TestB") 

instance = B() 
instance.method() # will call B.method() 
del B.method 
instance.method() # will now call A.method() 
del A.method 
instance.method() # will now raise AttributeError 

(またはdelattrを使用@ BrenBarnの答え)

関連する問題