2014-09-03 53 views
2

我有這個類:使用裝飾器來收集實例方法?

class Foo(object): 

    handlers = [] 

    def __init__(self): 
     pass 

    def run(self): 
     pass 

    def foo(self): 
     pass 

    def bar(self): 
     pass 

我怎麼能實現裝飾@collect_handler

class Foo(object): 

    handlers = [] 

    def __init__(self): 
     pass 

    def run(self): 
     pass  

    @collect_handler 
    def foo(self): 
     pass 

    @collect_handler 
    def bar(self): 
     pass 

使:

foo = Foo() 
foo.handlers # [foo, bar] 

這是可能的嗎?

+0

你想'handlers'返回綁定或未綁定實例方法? – dano 2014-09-03 02:36:38

+0

未綁定的方法 – wong2 2014-09-03 02:37:14

回答

2
class Foo(object): 
    handlers = [] 
    def collect_handler(handlers): 
     def wrapper(func): 
      handlers.append(func) 
      return func 
     return wrapper 
    collect_handler = collect_handler(handlers) 

    def __init__(self): 
     pass 

    def run(self): 
     pass  

    @collect_handler 
    def foo(self): 
     pass 

    @collect_handler 
    def bar(self): 
     pass 


foo = Foo() 
print(foo.handlers) 

產生

[<function foo at 0xb770d994>, <function bar at 0xb770d9cc>] 

這些都不是未結合的方法;他們只是普通的功能。 (沒有檢查第一個參數是否爲Foo的實例。)但是,它們應該已足夠。 (注意在Python3中沒有更多的未綁定方法;未綁定方法和普通函數之間的區別已被刪除。)

0

只是一種替代方式,不使用裝飾器。

f = Foo() 
[m for m in dir(f) if getattr(f,m).__doc__ == "COLLECT"] 

上述語句在Python中使用List comprehension。
dir是一個內置的函數,它將返回一個對象的所有屬性。
getattr是一個內置函數來檢索對象的屬性。
__doc__是一個python變量,它包含任何python構件的docstring。

這應該是你的類定義:

class Foo(object): 

    def __init__(self): 
     pass 

    def run(self): 
     pass  

    def foo(self): 
     "COLLECT" 
     pass 

    def bar(self): 
     "COLLECT" 
     pass