2015-08-17 69 views
1

在Python 3我有一個基類,從一個類派生:做一個裝飾呼叫的方法,具體的前置和後置方法的類

class Base: 
    # Tell the Base class to look and for pre/post 
    # functions the same name, and call them 
    def f(self): 
     print("f()") 

    def no_prepost(self): # should work, too 
     print("nothing") 

class Derived(Base): 
    def pre_f(self): 
     print("pre_f()") 

    def post_f(self): 
     print("post_f()") 

我想如果調用前置/後置的方法,他們存在,但沒有明確指出它們:

foo = Derived() 

# if exists: foo.pre_f() -- too verbose, do this automatically! 
foo.f() 
# if exists: foo.post_f() 

回答

1

裝飾器功能和一些類內省可以做到這一點。如果找到匹配功能的它被稱爲具有相同的參數:

def prepost(f): 
    def prepost_wrapper(self, *args, **kwargs): 
     pre_name = 'pre_' + f.__name__ 
     post_name = 'post_' + f.__name__ 
     if hasattr(self, pre_name): getattr(self, pre_name) (*args, **kwargs) 
     ret = f(self, *args, **kwargs) 
     if hasattr(self, post_name): getattr(self, post_name)(*args, **kwargs) 
     return ret 
    return prepost_wrapper 

class Base: 
    @prepost  
    def f(self, a, b=99): 
     print("f()", a, b) 
    @prepost 
    def missing(self): 
     print("nothing special here") 

class Derived(Base): 
    def pre_f(self, a, b=0): # the arguments must match! 
     print("pre_f()", a, b) 
    def post_f(self, a, b=1): 
     print("post_f()", a, b) 

foo = Derived() 
foo.f("abc") 
foo.missing() 
foo.f("xyz", 12) 

輸出:

pre_f() abc 0 
f() abc 99 
post_f() abc 1 
nothing special here 
pre_f() xyz 12 
f() xyz 12 
post_f() xyz 12