2017-08-29 16 views
2

pythonの使用3.6。私はクラスメソッドに一意の識別子を配置できるようにするコードを記述しようとしています。Pythonメソッド名の変更

ここでは例です:

def test(func): 
    def wrap(): 
     pass 
    wrap.__name__ += '_TEST' 
    return wrap 

class example: 
    @test 
    def method(self):pass 

コンソール:

import inspect 
Bar = example() 
inspect.getmembers(Bar, predicate=inspect.ismethod) 
Out[3]: 
[('method', # Name didn't change 
<bound method test.<locals>.wrap of <__main__.example object at 
0x000002670E073EF0>>)] 
Bar.method.__name__ 
Out[4]: 'wrap_TEST' 

私はクラスのメソッドをループのことができるようにとだけ、私は私のデコレータでマークされているものを実行したいです。これはできますか?

+1

メソッドルックアップでは実際の関数が返されません。関数ルックアップは実際には関数のバックラッパーです。 'Bar.method .__ func __.__ name_'をチェックすると、実際の関数の名前が変更されました。 –

+0

あなたはデコレータが達成しようとしていることをもっと説明できますか?このようにするのはあまりにも複雑すぎるようです。デコレータは実際に関数の動作方法を変更するか、名前を変更するだけですか? – MSeifert

+0

これはまた、 '' gemembers() 'がどのように動作するのか(https://github.com/python/cpython/blob/3.6/Lib/inspect.py#L326)、' dir() 'を使ってそれはインスタンスまたはクラス辞書に存在するので、常に 'method'を返すことになります。 –

答えて

1

ブールフラグを使用して関数をマークできます。ここに私の提案は次のとおりです。

import inspect 

def mark(func): 
    func.flag = True 
    return func 

class C: 
    @mark 
    def a(self): 
     pass 

    @mark 
    def b(self): 
     pass 

    def c(self): 
     pass 

methods = [m for n, m in inspect.getmembers(C) if hasattr(m, 'flag')] 
print([m.__name__ for m in methods]) #=> ['a', 'b'] 
3

のではなく、作成したメソッドの名前を変更しようと、あなたは、関数やメソッドは、メソッド自体にプロパティを割り当てるにはファーストクラスのオブジェクトであるという事実を使用することができます。

次のコードでは、テストするメソッドにプロパティTESTを追加する単純なデコレータを作成できます。

def test(func): 
    func.TEST = True 
    return func 


class example: 
    @test 
    def method(self): 
     pass 

ex = example() 
ex.method.TEST 
# returns: 
True 
+0

乾杯、それはまさにそれです! –

関連する問題