2017-08-29 85 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

乾杯,就是這樣! –