python decorators_python decorators

Contains:

1、decorators

2、functools

首先我们看下tornado中使用的装饰器

1、@tornado.web.authenticated

引用

Decorate methods with this to require that the user be logged in.

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了。

2、@tornado.web.asynchronous

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。

接下来,我们写个单利模式的装饰器:

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> <__main__.foo instance at> True

<__main__.bar instance at> <__main__.bar instance at> 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

引用

Design Goals:

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]

参考资料:

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

分享到:

18e900b8666ce6f233d25ec02f95ee59.png

72dd548719f0ace4d5f9bca64e1d7715.png

2013-03-28 23:36

浏览 1116

评论

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值