decorators' recipes

Download Decorators' recipes

Post on 16-Jun-2015

1.378 views

Category:

Technology

4 download

Embed Size (px)

DESCRIPTION

Yury Yurevich's topic "Decorators' recipes" from PyCamp Kyiv 2010 (also known as PyKyiv)

TRANSCRIPT

  • 1. yury.yurevich@equelli.com | http://pyobject.ruPyCamp Kyiv, , 2010. 1

2. >2000 >7 Python >5 Python >3 Ruby&Python >2 2 3. 3 4. 4 5. (2) = ( ) + + @_5 6. >>> def give_me_twice(x): ... return x*2 ... >>> function >>> def call_it(func, arg) ... return func(arg) ...>>> def make_strange(func) ... replaced = lambda x: func(x + 5) ... return replaced ...>>> strange_twice = make_strange(give_me_twice) 6 7. >>> def give_me_twice(x): ... return x*2 ...>>> def make_strange(func) ... replaced = lambda x: func(x + 5) ... return replaced ...>>> give_me_twice = make_strange(give_me_twice) 7 8. >>> def give_me_twice(x): ... return x*2 ...>>> def make_really_strange(func): ... def wrapper(z): ... res = func(z + 2) ... return res ... return wrapper ...>>> give_me_twice = make_really_strange(give_me_twice) >>> give_me_twice 8 9. ! >>> def give_me_twice(x): ... return x*2 ...>>> def make_really_omg(num): ... def decor(func): ... def wrapper(z): ... res = func(z + num) ... return res ... return wrapper ...return decor ...>>> decorator = make_really_omg(5) >>> decorator >>> give_me_twice = decorator(give_me_twice) >>> give_me_twice 9 10. >>> def make_really_strange(func): func wrapper ... def wrapper(z): ... res = func(z + 2) ... return res ... return wrapper>>> class make_really_strange(object): func ...def __init__(self, func): ...self.func = func ...def __call__(self, z): ...res = self.func(z + 2) ...return res 10 11. @name name(func) >>> def give_me_twice(x): ... return x*2 ...>>> give_me_twice = make_really_omg(5)(give_me_twice) >>> @make_really_omg(5) ... def give_me_twice(x): ... return x*2 ...11 12. ! @usecase @render_to('usecase_research.html') @usecase_provider @rules.apply_(default_rules) def research_unit(request):...usecase(render_to('usecase_research.html') (usecase_provider(rules.apply_(default_rules) (research_unit)))) 12 13. 13 14. , Python .14 15. 15 16. / () : @commit @cache >>> def infrastructure(func):... def wrapper(*args, **kwargs):... prepare_environ()... res = func(*args, **kwargs)... fix_environ()... return res... return wrapper16 17. 17 18. () : @register.tag (Django) >>> CALLBACKS = []>>> def callback(func):... def wrapper(*args, **kwargs):... res = func(*args, **kwargs)... assert res is not None... return res... CALLBACKS.append(wrapper)... return wrapper18 19. 19 20. API, : @render_to (Django, ) @permalink (Django) >>> def render_to(template): ... def decor(view): ... def wrapper(request, *args, **kwargs): ... context = view(request, *args, **kwargs) ... return render(template, request, context) ... return wrapper ... return decor 20 21. 21 22. : @login_required (Django) @validate (Pylons) >>> def login_required(view):... def wrapper(request, *args, **kwargs):... if request.user.is_authenticated():... return view(request, *args, **kwargs)... else:... return HttpResponseForbidden()... return wrapper22 23. - ajax_request def ajax_request(func): def wrapper(request, *args, **kwargs): if request.method == 'POST': response = func(request, *args, **kwargs) else: response = { 'error': { 'type': 405, 'message': 'Accepts POST only' } } if isinstance(response, dict): resp = JsonResponse(response) if 'error' in response: resp.status_code = response['error'].get('type', 500) return resp return response return functools.wraps(func)(wrapper) http://is.gd/7h6H7 23 24. - reg.simple_tag def simple_tag(self, func): params, xx, xxx, defaults = getargspec(func) class SimpleNode(Node):[...]compile_func = curry(generic_tag_compiler,params,defaults,getattr(func, "_decorated_function", func).__name__,SimpleNode)compile_func.__doc__ = func.__doc__ self.tag(getattr(func, "_decorated_function", func).__name__,compile_func)return funchttp://is.gd/7hdMu 24 25. - ;) http://self.maluke.com/25 26. P.S. http://www.siafoo.net/article/68 http://pypi.python.org/pypi/decorator http://tinyurl.com/decorator-guard 26 27. ? 27