python wraps decorator

from inspect import getmembers, getargspec
from functools import wraps
 
def wraps_decorator(f):
     @wraps (f)
     def wraps_wrapper( * args, * * kwargs):
         return f( * args, * * kwargs)
     return wraps_wrapper
 
class SomeClass( object ):
     @wraps_decorator
     def method( self , x, y):
         pass
 
obj = SomeClass()
for name, func in getmembers(obj, predicate = inspect.ismethod):
     print "Member Name: %s" % name
     print "Func Name: %s" % func.func_name
     print "Args: %s" % getargspec(func)[ 0 ]
 

class myDecorator( object ):
 
     def __init__( self , fn):
         print "inside myDecorator.__init__()"
         self .fn = fn
 
     def __call__( self ):
         self .fn()
         print "inside myDecorator.__call__()"
 
@myDecorator
def aFunction():
     print "inside aFunction()"
 
print "Finished decorating aFunction()"
 
aFunction()


你会发现,即使是你你用了functools的wraps,你在用getargspec时,参数也不见了。

要修正这一问,我们还得用Python的反射来解决,下面是相关的代码:

1
2
3
4
5
6
7
8
9
10
11
12
def get_true_argspec(method):
     argspec = inspect.getargspec(method)
     args = argspec[ 0 ]
     if args and args[ 0 ] = = 'self' :
         return argspec
     if hasattr (method, '__func__' ):
         method = method.__func__
     if not hasattr (method, 'func_closure' ) or method.func_closure is None :
         raise Exception( "No closure for method." )
 
     method = method.func_closure[ 0 ].cell_contents
     return get_true_argspec(method)

当然,我相信大多数人的程序都不会去getargspec。所以,用functools的wraps应该够用了。

class MyApp():
     def __init__( self ):
         self .func_map = {}
 
     def register( self , name):
         def func_wrapper(func):
             self .func_map[name] = func
             return func
         return func_wrapper
 
     def call_method( self , name = None ):
         func = self .func_map.get(name, None )
         if func is None :
             raise Exception( "No function registered against - " + str (name))
         return func()
 
app = MyApp()
 
@app .register( '/' )
def main_page_func():
     return "This is the main page."
 
@app .register( '/next_page' )
def next_page_func():
     return "This is the next page."
 
print app.call_method( '/' )
print app.call_method( '/next_page' )

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值