Python Decorators: различия между версиями
Материал из noname.com.ua
Перейти к навигацииПерейти к поискуSirmax (обсуждение | вклад) |
Sirmax (обсуждение | вклад) |
||
(не показаны 2 промежуточные версии этого же участника) | |||
Строка 1: | Строка 1: | ||
+ | [[Категория:Python]] |
||
=Декораторы в питоне= |
=Декораторы в питоне= |
||
Строка 83: | Строка 84: | ||
</PRE> |
</PRE> |
||
Т.е. в декоратор будут передано окружение. |
Т.е. в декоратор будут передано окружение. |
||
+ | * forum_app вернет ту ф-ю которая потом будет вызвана внутри декоратора |
||
− | * |
||
+ | **app = func(req, environ) - эта строчка в app запишет ф-ю (но не вызывая ее!) в зависимости от req. |
||
+ | **return app(environ, start_response) - а вернет на самом деле результат одной из ф-я обрабатывающих URL |
Текущая версия на 15:41, 28 сентября 2012
Декораторы в питоне
Разбор только одного примера, что был сложен для меня.
# coding=utf8 from webob import Request from wsgiref import simple_server from webob.exc import HTTPNotFound
webob - работа с HTTP wsgiref - веб сервер. можно использовать любой другой, и имя им легион.
Декоратор. Сама идея декоратора прекрасна - обернуть вызов ф-и в другую ф-ю и потом переопределить оригинальную. вот хорошие ссылки:
Это декоратор:
def webob_wrap(func): def wrapped(environ, start_response): aaa=100 req = Request(environ) app = func(req, environ) return app(environ, start_response) return wrapped
Это собственно функции которые борабатывают URL.
def list_topics_app(environ, start_response): start_response('200 OK', [('Content-type', 'text/plain')]) return "\n".join(["%s=%s" % (k, v) for k, v in environ.items()]) #return "123" def view_topic_app(environ, start_response): start_response('200 OK', [('Content-type', 'text/plain')]) return "\n".join(["%s=%s" % (k, v) for k, v in environ.items()]) #return "123" def fff(environ, start_response): start_response('200 OK', [('Content-type', 'text/plain')]) return "\n".join(["%s=%s" % (k, v) for k, v in environ.items()])
@webob_wrap def forum_app(req, environ): peek = req.path_info_peek() if not peek: return list_topics_app elif peek == 'new_topic': return new_topic_app elif peek.isdigit(): topic_id = int(req.path_info_pop()) environ['forum_app.topic_id'] = topic_id return view_topic_app else: return HTTPNotFound()
Запуск сервера
server = simple_server.WSGIServer( ('127.0.0.1', 8080), simple_server.WSGIRequestHandler, ) server.set_app(forum_app) server.serve_forever()
Логика работы приложения такая
- при любом запросе исполниться forum_app
- т.к. ф-я обернута в декоратор, то на самом деле вызов будет выглядеть так
forum_app=webob_wrap(forum_app): forum_app(environ, start_response)
Т.е. в декоратор будут передано окружение.
- forum_app вернет ту ф-ю которая потом будет вызвана внутри декоратора
- app = func(req, environ) - эта строчка в app запишет ф-ю (но не вызывая ее!) в зависимости от req.
- return app(environ, start_response) - а вернет на самом деле результат одной из ф-я обрабатывающих URL