博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
raw deferreds vs deferredGenerator vs inlineCallbacks
阅读量:6711 次
发布时间:2019-06-25

本文共 4448 字,大约阅读时间需要 14 分钟。

1.yield用法:
  必须在函数内出现,如果该函数包含yield,则是返回值是生成器,不必return任何东西
2. @defer.inlineCallbacks
  如果该decorator是生成器函数前,在此生成器函数,不阻塞,直接执行,但是返回值还是个生成器;

3.@property: 函数作属性使用

4.defer是事件调度的管理器,d.callback()时,defer中的函数系列才被执行;

5. reactor.callLater(1, d.callback, 3 ), 必须reactor.run()后才被调用;

 

6. defer.maybeDeferred()

Call the given function with the given arguments. If the returned object is a Deferred, return it. If the returned object is a Failure, wrap it with fail and return it. Otherwise, wrap it in succeed and return it. If an exception is raised, convert it to a Failure, wrap it in fail, and then return it.
def addCallbacks(self, callback, errback=None, callbackArgs=None, callbackKeywords=None, errbackArgs=None, errbackKeywords=None): (source)
::Add a pair of callbacks (success and error) to this Deferred.
These will be executed when the 'master' callback is run.
def addBoth(self, callback, *args, **kw): (source)
::Convenience method for adding a single callable as both a callback and an errback.
def chainDeferred(self, d): (source)
::Chain another Deferred to this Deferred.
This method adds callbacks to this Deferred to call d's callback or errback, as appropriate. It is merely a shorthand way of performing the following:

self.addCallbacks(d.callback, d.errback)

When you chain a deferred d2 to another deferred d1 with d1.chainDeferred(d2), you are making d2 participate in the callback chain of d1. Thus any event that fires d1 will also fire d2. However, the converse is not true; if d2 is fired d1 will not be affected.
def succeed(result):
:: Return a Deferred that has already had '.callback(result)' called.
exam:
#d = defer.succeed(10).addCallback(h)
d = defer.succeed(10)
d.addCallback(h)

 

 

另外:

先简单说一下python decorator:
  1. @A
  2. def f ():
  3.     …
  4. 这种形式是decorator不带参数的写法。最终 Python 会处理为:
  5. f = A(f)

如此这样,

  1. from twisted.internet import defer
  2. from twisted.web import client
  3. from twisted.internet import reactor
  4. import sys
  5. @defer.inlineCallbacks
  6. def enqueueTaskToDisplayURL(url):
  7.     try:
  8.         data = yield client.getPage(url)
  9.         print data
  10.     except Exception, e:
  11.         print >> sys.stderr, "Error:", e
  12.         return;
  13.     finally: reactor.stop()
  14. if __name__ == "__main__":
  15.     enqueueTaskToDisplayURL("http://example.com/")
  16.     reactor.run()

enqueueTaskToDisplayURL = defer.inlineCallbacks(enqueueTaskToDisplayURL)

把enqueueTaskToDisplayURL当做了一个callback函数。谁的callback呢?

我们注意到enqueueTaskToDisplayURL同时它又是一个generator,执行到第一个yeild的时候,便会返回yeild后异步函数的defer对象。则callback就add到了该defer对象。

当getPage的数据ready的时候,generator通过send(data)返回数据。generator便从第一个yield后开始执行。

总结:

1)通过@defer.inlineCallbacks + yield, 帮助程序员将异步的代码写成了同步的方式。

2)Twisted's @inlineCallbacks decorator basically does this for you; whenever you yield a deferred (Twisted's representation of an ongoing operation), the rest of the generator is registered as the callback for when the operation is finished.

------------------------------------我是分割线----------------------------------------------

摘一下从twistedmatrix.com上搞的document:

 

inlineCallbacks helps you write Deferred-using code that looks like a regular sequential function. This function uses features of Python 2.5 generators. If you need to be compatible with Python 2.4 or before, use the function instead, which accomplishes the same thing, but with somewhat more boilerplate. For example:

@inlineCallBacks def thingummy(): thing = yield makeSomeRequestResultingInDeferred() print thing #the result! hoorj!

When you call anything that results in a , you can simply yield it; your generator will automatically be resumed when the Deferred's result is available. The generator will be sent the result of the with the 'send' method on generators, or if the result was a failure, 'throw'.

 

Your inlineCallbacks-enabled generator will return a object, which will result in the return value of the generator (or will fail with a failure object if your generator raises an unhandled exception). Note that you can't use return result to return a value; use returnValue(result) instead. Falling off the end of the generator, or simply using return will cause the to have a result of None.

 

The returned from your deferred generator may errback if your generator raised an exception:

@inlineCallbacks def thingummy(): thing = yield makeSomeRequestResultingInDeferred() if thing == 'I love Twisted': # will become the result of the Deferred returnValue('TWISTED IS GREAT!') else: # will trigger an errback raise Exception('DESTROY ALL LIFE')

 

转载于:https://www.cnblogs.com/zhangjing0502/archive/2012/05/17/2506659.html

你可能感兴趣的文章
mvc 使用预置队列类型存储异常对象
查看>>
seqtk 的安装和使用
查看>>
oracle-rman-2
查看>>
OC第三天(内存管理)
查看>>
DataFactory
查看>>
POJ 1410 Intersection
查看>>
Java命名规范
查看>>
程序员,代码,理想,老男孩
查看>>
MATLAB GUI新手备忘录(转)
查看>>
mysql sql语句大全
查看>>
php 调试工具及学习PHP垃圾回收机制了解引用计数器的概念
查看>>
Jetty安装配置
查看>>
【Lucene3.6.2入门系列】第10节_Tika
查看>>
Java工厂模式
查看>>
hdu3635 Dragon Balls(带权并查集)
查看>>
java Socket用法详解(转)
查看>>
gitosis使用笔记
查看>>
华为-on练习--身高找到最好的二人
查看>>
指定账户访问共享文件
查看>>
T-SQL—理解CTEs
查看>>