`

Tornado gen简介

阅读更多
[size=small]
Contains:

  • 1、iterator
  • 2、generator
  • 3、yield expressions
  • 4、tornado.gen

一、迭代器

引用

    Python supports a concept of iteration over containers. This is implemented using two distinct methods; these are used to allow user-defined classes to support iteration. Sequences, described below in more detail, always support the iteration methods.
    Iteration is a process implying iterables (implementing the __iter__() method) and iterators (implementing the __next__() method). Iterables are any objects you can get an iterator from. Iterators are objects that let you iterate on iterables.

    The iterator objects themselves are required to support the following two methods, which together form the iterator protocol:

1、iterator.__iter__()
     Return the iterator object itself. This is required to allow both containers and iterators to be used with the for and in statements. This method corresponds to the tp_iter slot of the type structure for Python objects in the Python/C API.
2、iterator.next()
     Return the next item from the container. If there are no further items, raise the StopIteration exception. This method corresponds to the tp_iternext slot of the type structure for Python objects in the Python/C API.

二、生成器

引用
    Python’s generators provide a convenient way to implement the iterator protocol. If a container object’s __iter__() method is implemented as a generator, it will automatically return an iterator object (technically, a generator object) supplying the __iter__() and next() methods. More information about generators can be found in the documentation for the yield expression.
    Generators are iterables, but you can only read them once. It's because they do not store all the values in memory

简单的讲,Generator在需要时返回中间值,能够保存当前的状态,等待下一次的返回要求。
迭代到下一次的调用时,所使用的参数都是第一次所保留下的,即是说,在整个所有函数调用的参数都是第一次所调用时保留的,而不是新创建的
    Generators functions allow you to declare a function that behaves like an iterator, i.e. it can be used in a for loop.
引用
    The performance improvement from the use of generators is the result of the lazy (on demand) generation of values, which translates to lower memory usage. Furthermore, we do not need to wait until all the elements have been generated before we start to use them. This is similar to the benefits provided by iterators, but the generator makes building iterators easy.

   This can be illustrated by comparing the range and xrange built-ins of Python 2.x.
Both range and xrange represent a range of numbers, and have the same function signature, but range returns a list while xrange returns a generator (at least in concept; the implementation may differ).
sum_of_numbers = sum(range(1000000))
sum_of_numbers = sum(xrange(1000000))
    When we use range we build a 1,000,000 element list in memory and then find its sum. This is a waste, considering that we use these 1,000,000 elements just to compute the sum.
    This waste becomes more pronounced as the number of elements (our n) becomes larger, the size of our elements become larger, or both.
    On the other hand, when we use xrange, we do not incur the cost of building a 1,000,000 element list in memory. The generator created by xrange will generate each number, which sum will consume to accumulate the sum.
    In the case of the "range" function, using it as an iterable is the dominant use-case, and this is reflected in Python 3.x, which makes the range built-in return a generator instead of a list.
引用
    Note: a generator will provide performance benefits only if we do not intend to use that set of generated values more than once.

在实现上,generator并不是生成一个列表,然后再由for对元素一个一个进行处理,而是一次只返回一个元素(用yield语句)并保存generator的状态,等下次被调用时再从当前状态往下执行,这样可以省却保存整个大列表的存储代价。
什么时候适合使用生成器:
  • 1、You don't need to read the values twice.
  • 2、You can have a lot of children and you don't want them all stored in memory.

三、yield expressions
    
引用
    The yield expression is only used when defining a generator function, and can only be used in the body of a function definition. Using a yield expression in a function definition is sufficient to cause that definition to create a generator function instead of a normal function.
     When a generator function is called, it returns an iterator known as a generator iterator, or more commonly, a generator. The body of the generator function is executed by calling the generator’s next() method repeatedly until it raises an exception.
     When a yield statement is executed, the state of the generator is frozen and the value of expression_list is returned to next()‘s caller. By “frozen” we mean that all local state is retained, including the current bindings of local variables, the instruction pointer, and the internal evaluation stack: enough information is saved so that the next time next() is invoked, the function can proceed exactly as if the yield statement were just another external call.

   Yield is a keyword that is used like return, except the function will return a generator.
   The first time your function will run, it will run from the beginning until it hits yield, then it'll return the first value of the loop. Then, each other call will run the loop you have written in the function one more time, and return the next value, until there is no value to return.
    yield简单说来就是一个生成器,生成器是这样一个函数,它记住上一次返回时咋函数体中的位置。对生成器函数的第二次(或第n次)调用跳转至该函数中间,而上次调用的所有局部变量都保持不变。
可以说带有yield的函数在python中被称之为generator.
一个带有 yield 的函数就是一个 generator,它和普通函数不同,生成一个 generator 看起来像函数调用,但不会执行任何函数代码,直到对其调用 next()(在 for 循环中会自动调用 next())才开始执行。虽然执行流程仍按函数的流程执行,但每执行到一个 yield 语句就会中断,并返回一个迭代值,下次执行时从 yield 的下一个语句继续执行。看起来就好像一个函数在正常执行的过程中被 yield 中断了数次,每次中断都会通过 yield 返回当前的迭代值。

四、tornado gen

引用
    tornado.gen is a generator-based interface to make it easier to work in an asynchronous environment. Code using the gen module is technically asynchronous, but it is written as a single generator instead of a collection of separate functions.

decorator:
tornado.gen.engine(func)

Decorator for asynchronous generators.
    Any generator that yields objects from this module must be wrapped in this decorator. The decorator only works on functions that are already asynchronous. For RequestHandler get/post/etc methods, this means that both the tornado.web.asynchronous and tornado.gen.engine decorators must be used (for proper exception handling, asynchronous should come before gen.engine). In most other cases, it means that it doesn’t make sense to use gen.engine on functions that don’t already take a callback argument.
Yield points:
Instances of the following classes may be used in yield expressions in the generator.
class tornado.gen.Task(func, *args, **kwargs)

Runs a single asynchronous operation.
    Takes a function (and optional additional arguments) and runs it with those arguments plus a callback keyword argument. The argument passed to the callback is returned as the result of the yield expression.
    A Task is equivalent to a Callback/Wait pair (with a unique key generated automatically)

class tornado.gen.Callback(key)

class tornado.gen.Wait(key)

class tornado.gen.WaitAll(keys)
示例:
class GenAsyncHandler(RequestHandler):
    @asynchronous
    @gen.engine
    def get(self):
        http_client = AsyncHTTPClient()
        response = yield gen.Task(http_client.fetch, "http://example.com")
        do_something_with_response(response) 
        self.render("template.html")


参考资料:
http://wiki.python.org/moin/Generators
http://linuxgazette.net/100/pramode.html
http://www.python.org/dev/peps/pep-0234/
http://www.python.org/dev/peps/pep-0255/
http://www.pythonclub.org/python-basic/yield
http://docs.python.org/2/library/stdtypes.html
http://zouyesheng.com/generator-for-async.html
http://www.tornadoweb.org/documentation/gen.html
http://blog.xiaogaozi.org/2012/09/21/understanding-tornado-dot-gen/
http://stackoverflow.com/questions/7883962/where-to-use-yield-in-python-best
http://stackoverflow.com/questions/231767/the-python-yield-keyword-explained
[/size]
分享到:
评论

相关推荐

    tornado协程示例

    from tornado import gen from tornado.httpclient import AsyncHTTPClient @gen.coroutine def coroutine_visit(): http_client = AsyncHTTPClient() response = yield http_client.fetch("www.baidu.com") ...

    tornado celery example

    1、tornado server 2、使用异步gen.coroutine 3、异步任务,使用future,callback 4、celery task,使用sqlite 或 redis 5、脚本部署启动。 文件如下: example.py run_shell.py setting.py stop.sh tc.db redis_...

    nats.py2:用于 NATS 的基于 Tornado 的 Python 2 客户端

    NATS - 基于 Tornado 的 Python 2 客户端 用于Python 异步客户端。 支持的平台 应该与使用 (小于 6.0)的兼容。 对于 Python 3,请检查 入门 pip install nats-client 基本用法 import tornado . ioloop import ...

    learning-tornado-src:Tornado框架源码学习笔记

    tornado作为web框架和异步网络库,代码量过多,因此在分析tornado源码时,可以选择一些比较重要的模块来阅读,方式:current.py,gen.py,tcpserver.py,httpserver.py,ioloop .py,iostream.py,web.py等 ...

    Tornado高并发处理方法实例代码

    本文主要分享的是一则关于Tornado高并发处理方法的实例,具体如下: ...import tornado.gen from tornado.concurrent import run_on_executor from concurrent.futures import ThreadPoolExecutor import time from

    Postgresql-async-tornado:用于异步 PostgreSQL 查询的模块,适用于 Tornado 和 psycopg2

    Postgresql-异步龙卷风用于异步... gen . coroutine def get ( self ): mid = self . get_argument ( "m" , '' ) r = yield db . query ( """SELECT * FROM foo WHERE id > %s """ , ( mid , )) context = dict ( r = r

    Tornado-Tester:龙卷风的测试工具

    from tornado_tester import gen_test, Tester from yourapplication import app class Test(unittest.TestCase): @gen_test def test_app(): with Tester(app) as tester: response = yield tester.http_client...

    tornado-whois:Python Tornado异步Whois客户端

    from tornado import ioloop, gen from tornadowhois import AsyncWhoisClient @gen.coroutine def main(): data = yield AsyncWhoisClient().lookup("example.com") print data ioloop.IOLoop.current().run_sync...

    tornado-smtp:Tornado 的异步 SMTP 客户端。 smtplib.SMTP 的薄包装

    龙卷风-smtp Tornado 的异步 SMTP 客户端。... RequestHandler ): @ gen . coroutine def get ( self ): smtp = TornadoSMTP ( '<smtp>' ) yield smtp . starttls () yield smtp . login ( '<username>' , '<

    Python-Web自测试卷答案.docx

    在Tornado中使用tornado.gen模块执行异步请求。 4.在Tornado中使用tornado.template模块实现模板引擎。 5.WSGI是Python应用程序或框架和Web服务器之间的一种接口。 简答题: 1. 什么是CSS,它的作用是什么? CSS是...

    tornadio2:Tornado框架之上的Python socket.io服务器实现

    TornadIO2 免责声明 不幸的是,Socket.IO 0.8分支已被放弃,存在大量的错误,并且没有得到修复。...支持基于生成器的异步代码(tornado.gen API) 统计信息捕获(每秒数据包等) 什么是Socket.IO? Socket

    ioloop_redis:另一个用于 Tornado 的异步 redis 库,简短而直观

    gen import coroutine from redis_client import * _queue = AsyncRedis ( 'redis://localhost:6379/1' ) class HelloworldHandler ( RequestHandler ): @ coroutine def get ( self ): next_cmd = yield _q

    python 5个顶级异步框架推荐

    Python在3.4引入了 asyncio 库,3.6新增了关键字 async和await,此后,异步框架迅速发展了起来,性能上能和Node.js比肩,除非是CPU密集型任务,否则没有理由不适用异步... 协同程序和其他原语(tornado.gen,tornado.l

    freeswitch-eventsocket:这是一个正在进行的抽象类,用于处理 freeswitch 的 eventsocket 命令行

    自由切换事件套接字这是一个正在进行的抽象类,用于处理 freeswitch 的... gen import coroutine , Returnclass TestServer ( eventsocket . BaseEventSocket , TCPServer ): @ coroutine def handle_stream ( self , s

    storm:龙卷风的简单ORM

    风暴 龙卷风的简单ORM 风暴代表对于s impleŤornadoöbjectřelational中号apping。... gen import coroutine from tornado . ioloop import IOLoop class User ( Model ): pass @ coroutine def main ():

    Tornado协程在python2.7如何返回值(实现方法)

    @gen.coroutine def get(self): response = httpclient('http://www.baidu.com') self.write(response.body) @gen.coroutine def httpClient(url): result = yield httpclient.AsyncHTTPClient().fetch(url) ...

    解决Jupyter因卸载重装导致的问题修复

    因为一些原因,卸载了Anaconda2的版本,转向3..发现Jupyter挂了.百思不得其解.后来了解到是因为内核找不到的问题导致的.这里整理了一下处理办法 ... File "c:\program files\python36\lib\site-packages\tornado\gen.py

    jupyter notebook运行命令没有反应,右上报错这个

    有没有哪位 大佬知道这个该怎么解决呀,萌新一枚初学python,弄了一整天了 都还没有弄好 自己 也按照网上说的都做了都没用,也重新安装过了...File “C:\ProgramData\Anaconda3\lib\site-packages\tornado\gen.py”, li

    TorMySQL:PyMySQL的最高性能异步MySQL驱动程序

    TorMySQL的 最高性能的异步MySQL驱动程序。 PyPI页面: ://pypi.python.org/pypi/tormysql ...from tornado import gen import tormysql pool = tormysql.ConnectionPool( max_connections = 20, #max open c

    Python多线程、异步+多进程爬虫实现代码

    安装Tornado 省事点可以直接用grequests库,下面用的是tornado的异步client。 异步用到了tornado,根据官方文档的例子修改得到...from tornado import httpclient, gen, ioloop, queues import traceback class AsySpi

Global site tag (gtag.js) - Google Analytics