python decorators

[b]Contains[/b]:
[list]
[*]1、decorators
[*]2、functools
[/list]
首先我们看下tornado中使用的装饰器
[b]1、@tornado.web.authenticated[/b]
[quote]Decorate methods with this to require that the user be logged in. [/quote]

def authenticated(method):
"""Decorate methods with this to require that the user be logged in."""
@functools.wraps(method)
def wrapper(self, *args, **kwargs):
if not self.current_user:
if self.request.method in ("GET", "HEAD"):
url = self.get_login_url()
if "?" not in url:
if urlparse.urlsplit(url).scheme:
# if login url is absolute, make next absolute too
next_url = self.request.full_url()
else:
next_url = self.request.uri
url += "?" + urllib.urlencode(dict(next=next_url))
self.redirect(url)
return
raise HTTPError(403)
return method(self, *args, **kwargs)
return wrapper

接下来代码需要验证用户登陆的方法都可以使用这个装饰器,通过使用这个装饰器可以简化很多重复验证的代码,只需要在方法上面加上@tornado.web.authenticated就ok了。
[b]2、@tornado.web.asynchronous[/b]

def asynchronous(method):
@functools.wraps(method)
def wrapper(self, *args, **kwargs):
if self.application._wsgi:
raise Exception("@asynchronous is not supported for WSGI apps")
self._auto_finish = False
with stack_context.ExceptionStackContext(
self._stack_context_handle_exception):
return method(self, *args, **kwargs)
return wrapper

这个装饰器的会把self._auto_finish 置为 False。
接下来,我们写个[b]单利模式[/b]的装饰器:

def singleton(cls):
instances = {}
def get_instance():
if cls not in instances:
instances[cls] = cls()
return instances[cls]
return get_instance

@singleton
class Foo:
def __init__(self):
pass

class Bar:
def __init__(self):
pass

f = Foo()
m = Foo()
print f,m,f == m

a = Bar()
b = Bar()
print a,b,a == b

result is :
<__main__.Foo instance at 0x103152c20> <__main__.Foo instance at 0x103152c20> True
<__main__.Bar instance at 0x103152c68> <__main__.Bar instance at 0x103152cb0> False
@singleton这个装饰器实现了类的单例模式,可以确保类只会被实例化一次。

使用装饰器对参数以及方法返回结果的验证方法:

#-*-coding:utf-8-*-

def accepts(*types):
def check_accepts(f):
# assert len(types) == f.func_code.co_argcount
def new_f(*args, **kwds):
for (a, t) in zip(args, types):
assert isinstance(a, t), \
"arg %r does not match %s" % (a,t)
return f(*args, **kwds)
new_f.func_name = f.func_name
return new_f
return check_accepts

def returns(rtype):
def check_returns(f):
def new_f(*args, **kwds):
result = f(*args, **kwds)
assert isinstance(result, rtype), \
"return value %r does not match %s" % (result,rtype)
return result
new_f.func_name = f.func_name
return new_f
return check_returns

@accepts(int, (int,float))
@returns((int,float))
def func(arg1, arg2):
return arg1 * arg2

print func(1,2.0)



def check_param_isvalid():
def check(method):
def check_param(*args,**kwargs):
for a in args:
assert isinstance(a, int),"arg %r does not match %s" % (a,int)
assert a > 100000,"arg %r must gt 100000" % a
return method(*args, **kwargs)
return check_param
return check

@check_param_isvalid()
def foo(*args):
print args

foo(200000,5000)

result:
assert a > 100000,"arg %r must gt 100000" % a
AssertionError: arg 5000 must gt 100000
[quote][b]Design Goals[/b]:

The new syntax should


* work for arbitrary wrappers, including user-defined callables and the existing builtins classmethod() and staticmethod(). This requirement also means that a decorator syntax must support passing arguments to the wrapper constructor
* work with multiple wrappers per definition
* make it obvious what is happening; at the very least it should be obvious that new users can safely ignore it when writing their own code
* be a syntax "that ... [is] easy to remember once explained"
* not make future extensions more difficult
* be easy to type; programs that use it are expected to use it very frequently
* not make it more difficult to scan through code quickly. It should still be easy to search for all definitions, a particular definition, or the arguments that a function accepts
* not needlessly complicate secondary support tools such as language-sensitive editors and other "toy parser tools out there [12]"
* allow future compilers to optimize for decorators. With the hope of a JIT compiler for Python coming into existence at some point this tends to require the syntax for decorators to come before the function definition
* move from the end of the function, where it's currently hidden, to the front where it is more in your face [13][/quote]


参考资料:
http://www.python.org/dev/peps/pep-0318/
http://wiki.python.org/moin/PythonDecorators
http://wiki.python.org/moin/PythonDecoratorLibrary
http://blog.csdn.net/beckel/article/details/3585352
http://blog.csdn.net/beckel/article/details/3945147
http://www.cnblogs.com/huxi/archive/2011/03/01/1967600.html
http://mrcoles.com/blog/3-decorator-examples-and-awesome-python/
http://stackoverflow.com/questions/308999/what-does-functools-wraps-do
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值