最近很多小伙伴都在问PythonTwisted代理-如何拦截数据包和python拦截tcp数据包这两个问题,那么本篇文章就来给大家详细解答一下,同时本文还将给你拓展pip安装提示Twisted错误问题
最近很多小伙伴都在问Python Twisted代理-如何拦截数据包和python拦截tcp数据包这两个问题,那么本篇文章就来给大家详细解答一下,同时本文还将给你拓展pip安装提示Twisted错误问题(Python3.6.4安装Twisted错、Python 2.7 安装twisted、python twisted deferred、Python Twisted pip软件包与Python3不兼容等相关知识,下面开始了哦!
本文目录一览:- Python Twisted代理-如何拦截数据包(python拦截tcp数据包)
- pip安装提示Twisted错误问题(Python3.6.4安装Twisted错
- Python 2.7 安装twisted
- python twisted deferred
- Python Twisted pip软件包与Python3不兼容
Python Twisted代理-如何拦截数据包(python拦截tcp数据包)
我正在尝试使用Python打印出HTTP响应的正文。
这是我的代码sofer:
from twisted.web import proxy, httpfrom twisted.internet import reactorfrom twisted.python import logimport syslog.startLogging(sys.stdout)class ProxyFactory(http.HTTPFactory): protocol=proxy.Proxyreactor.listenTCP(8080, ProxyFactory())reactor.run()
当我将浏览器连接到localhost:8080时,可以看到我的所有请求都通过本地运行的Python代理定向。但是,我如何1)打印出响应正文并2)在将响应正文发送回浏览器之前对其进行编辑?
我希望有人可以指出正确的方向-请记住,我对Python还是很陌生!
答案1
小编典典覆盖协议的dataReceived方法(在您的情况下为proxy.Proxy),并使用该方法处理数据修改:
from twisted.web import proxy, httpfrom twisted.internet import reactorfrom twisted.python import logimport syslog.startLogging(sys.stdout)class MyProxy(proxy.Proxy): def dataReceived(self, data): # Modify the data here print data # perform the default functionality on modified data return proxy.Proxy.dataReceived(self, data)class ProxyFactory(http.HTTPFactory): protocol=MyProxyfactory = ProxyFactory()reactor.listenTCP(8080, factory)reactor.run()
pip安装提示Twisted错误问题(Python3.6.4安装Twisted错
当我们在安装scrapy的过程中出现了Twisted错误,当我们有继续安装Twisted的时候,又继续报错,通过一系列的查询和了解,终于发现了问题,现在就来和大家一起解决这个复杂的BUG……
环境
Python3.6.4 + Windows 10
问题描述
当我在安装pip install scrapy的过程中报Twisted的错误;
当我又继续安装pip install Twisted的时候,还是依然报错。
问题原因
当我从网上搜寻了很多资料后发现,原来是Twisted和高版本的Python有兼容性的问题。
解决方法
我们通过在Python扩展包的非官方Windows二进制文件中找到相应的Twisted文件扩展包(我们可以通过Ctrl+F快捷键来搜索Twisted,然后找到该文件),然后下载:
大家可以看到,我的Python是3.6版本的,我的操作系统是Windows 10 64位的,所以我选择的是cp36,win_amd64,大家可以根据自己的Python版本和电脑操作系统的型号来进行下载。接下来大家进入用管理员的方式运行命令提示符(如何运行上一章有讲如何进入命令行的特权模式),找到Python的安装根目录中的的Scripts目录下,比如说我的Python安装在C盘:C:\Program Files\Python36\Scripts
然后将刚才下载的Twisted包复制到Scripts目录下面,并用pip进行安装:
- C:\Program Files\Python36\Scriptspip install Twisted-17.9.0-cp36-cp36m-win_amd64.whl
– 最后一步,显示:
- Successfully installed Twisted-17.9.0
表示你安装成功了,显示根据自己的版本而定。
PS:如果在安装过程中需要pywin32的话,大家也可以使用pip命令来进行安装该包,pip install pywin32
总结
到此这篇关于pip安装提示Twisted错误问题(Python3.6.4安装Twisted错误)的文章就介绍到这了,更多相关python3.6 安装Twisted出错内容请搜索本站以前的文章或继续浏览下面的相关文章希望大家以后多多支持本站!
Python 2.7 安装twisted
1.安装twisted
下载地址:https://pypi.python.org/simple/twisted
找对应版本和对应系统版本,下载exe安装即可
2.安装zope.interface
下地址:https://pypi.python.org/simple/zope.interface/
一样是找对应版本和对应系统版本,下载exe安装即可
两个安装成功之后,在C:\Python27\Lib\site-packages目录下看到对应的文件夹
3.验证结果
没报错完美运行
注:我在安装完成之后,使用PyCharm导入twisted模块一直报错,console窗口运行正常。
解决办法如下:
大概意思就PyCharm重新安装编译一次所有模块,再到PyCharm使用import 导入 没报错正常运行
python twisted deferred
<?xml version="1.0"?>
<html lang="en" xml:lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta name="generator" content="HTML Tidy for Windows (vers 1st November 2003), see www.w3.org" /> <title>Twisted Documentation: Deferreds are beautiful! (A Tutorial)</title> <link href="../howto/stylesheet.css" type="text/css" rel="stylesheet" /> </head> <body bgcolor="white"> <h1>Deferreds are beautiful! (A Tutorial)</h1> <div> <ol> <li><a href="#auto0">Introduction</a></li> <li><a href="#auto1">A simple example</a></li> <li><a href="#auto2">Errbacks</a></li> <li> <ul> <li><a href="#auto3">Failure in requested operation</a></li> <li><a href="#auto4">Exceptions raised in callbacks</a></li> <li><a href="#auto5">Exceptions will only be handled by errbacks</a></li> <li><a href="#auto6">Handling an exception and continuing on</a></li> </ul> </li> <li><a href="#auto7">addBoth: the deferred version of finally</a></li> <li><a href="#auto8">addCallbacks: decision making based on previous success or failure</a></li> <li><a href="#auto9">Hints, tips, common mistakes, and miscellaney</a></li> <li> <ul> <li><a href="#auto10">The deferred callback chain is stateful</a></li> <li><a href="#auto11">Don''t call .callback() on deferreds you didn''t create!</a></li> <li><a href="#auto12">Callbacks can return deferreds</a></li> </ul> </li> <li><a href="#auto13">Conclusion</a></li> </ol> </div> <div> <h2>Introduction<a name="auto0" id="auto0"></a></h2> <p>Deferreds are quite possibly the single most confusing topic that a newcomer to Twisted has to deal with. I am going to forgo the normal talk about what deferreds are, what they aren''t, and why they''re used in Twisted. Instead, I''m going show you the logic behind what they <strong>do</strong>.</p> <p>对Twisted的新手来说,deferred或许是最令他们感到困惑的东西。我准备先把“它是什么”, “不是什么”以及“为什么Twisted必须要用它”之类的普通问题先放一放。这里我先给你介绍一下它的工作原理。</p>
<p>A deferred allows you to encapsulate the logic that you''d normally use to make a series of function calls after receiving a result into a single object. In the examples that follow, I''ll first show you what''s going to go on behind the scenes in the deferred chain, then show you the deferred API calls that set up that chain. All of these examples are runnable code, so feel free to play around with them.</p> <p>deferred的作用是,能让你把通常情况下,当一个对象收到一个结果之后会产生一系列方法调用的处理逻辑封装起来。下面我们会举一些例子,我会告诉你在deferred链背后究竟发生了些什么。此外我还会演示怎样用deferred API来构建这个链。这些代码都能运行,所以尽管试吧。</p>
<h2>A simple example<a name="auto1" id="auto1"></a></h2>
First, a simple example so that we have something to talk about:
<div> <pre> <span>#!/usr/bin/python2.3 </span> <span>from</span> <span>twisted</span>.<span>internet</span> <span>import</span> <span>defer</span> <span>from</span> <span>twisted</span>.<span>python</span> <span>import</span> <span>failure</span>, <span>util</span>
<span>""" here we have the simplest case, a single callback and a single errback """</span>
<span>num</span> = <span>0</span> <span>def</span> <span>handleFailure</span>(<span>f</span>): <span>print</span> <span>"errback"</span> <span>print</span> <span>"we got an exception: %s"</span> % (<span>f</span>.<span>getTraceback</span>(),) <span>f</span>.<span>trap</span>(<span>RuntimeError</span>)
<span>def</span> <span>handleResult</span>(<span>result</span>): <span>global</span> <span>num</span>; <span>num</span> += <span>1</span> <span>print</span> <span>"callback %s"</span> % (<span>num</span>,) <span>print</span> <span>"\tgot result: %s"</span> % (<span>result</span>,) <span>return</span> <span>"yay! handleResult was successful!"</span>
<span>def</span> <span>behindTheScenes</span>(<span>result</span>): <span># equivalent to d.callback(result) </span> <span>if</span> <span>not</span> <span>isinstance</span>(<span>result</span>, <span>failure</span>.<span>Failure</span>): <span># ---- callback</span> <span>try</span>: <span>result</span> = <span>handleResult</span>(<span>result</span>) <span>except</span>: <span>result</span> = <span>failure</span>.<span>Failure</span>() <span>else</span>: <span># ---- errback</span> <span>pass</span>
<span>if</span> <span>not</span> <span>isinstance</span>(<span>result</span>, <span>failure</span>.<span>Failure</span>): <span># ---- callback</span>
<span>pass</span>
<span>else</span>: <span># ---- errback</span>
<span>try</span>:
<span>result</span> = <span>handleFailure</span>(<span>result</span>)
<span>except</span>:
<span>result</span> = <span>failure</span>.<span>Failure</span>()
<span>def</span> <span>deferredExample</span>(): <span>d</span> = <span>defer</span>.<span>Deferred</span>() <span>d</span>.<span>addCallback</span>(<span>handleResult</span>) <span>d</span>.<span>addErrback</span>(<span>handleFailure</span>)
<span>d</span>.<span>callback</span>(<span>"success"</span>)
<span>if</span> <span>name</span> == <span>''main''</span>: <span>behindTheScenes</span>(<span>"success"</span>) <span>print</span> <span>"\n-------------------------------------------------\n"</span> <span>global</span> <span>num</span>; <span>num</span> = <span>0</span> <span>deferredExample</span>() </pre>
<div>Source listing - <a href="../listings/deferred/deferred_ex.py"><span>../listings/deferred/deferred_ex.py</span></a></div> </div> <p>And the output: (since both methods in the example produce the same output, it will only be shown once.)</p> <p>输出如下:(鉴于两次调用的输出是相同的,这里就只打印一次了。)</p>
<pre> callback 1 got result: success </pre>
<p>Here we have the simplest case. A deferred with a single callback and a single errback. Normally, a function would create a deferred and hand it back to you when you request an operation that needs to wait for an event for completion. The object you called then does <code>d.callback(result)</code> when the results are in.</p>
<p>这是最简单的例子。只带一个callback和一个errback的defrred。通常你会建一个会返回deferred的函数,然后当你发出一个需要等一段时间才能结束的请求时,你就可以调用这个方法会获取一个deferred。等到结果出来了,你再用<code>d.callback(result)</code>。</p>
<p>The thing to notice is that there is only one result that is passed from method to method, and that the result returned from a method is the argument to the next method in the chain. In case of an exception, result is set to an instance of <code base="twisted.python.failure">Failure</code> that describes the exception.</p>
<p>值得注意的是,所有方法都只能传一个参数,在这个链里前一个方法的返回值就是后一个方法的参数。万一碰到异常,twisted就会把返回值设成相应的<code base="twisted.python.failure">Failure</code>实例。</p>
<h2>Errbacks<a name="auto2" id="auto2"></a></h2> <h3>Failure in requested operation<a name="auto3" id="auto3"></a></h3> <h3>操作请求失败了</h3>
<p>Things don''t always go as planned, and sometimes the function that returned the deferred needs to alert the callback chain that an error has occurred.</p> <p>事情不会总是按着计划走,有时你得在函数里设计好,万一发生了错误,callback链该做什么调整。</p> <div> <pre> <span>#!/usr/bin/python2.3 </span> <span>from</span> <span>twisted</span>.<span>internet</span> <span>import</span> <span>defer</span> <span>from</span> <span>twisted</span>.<span>python</span> <span>import</span> <span>failure</span>, <span>util</span>
<span>""" this example is analagous to a function calling .errback(failure) """</span>
<span>class</span> <span>Counter</span>(<span>object</span>): <span>num</span> = <span>0</span>
<span>def</span> <span>handleFailure</span>(<span>f</span>): <span>print</span> <span>"errback"</span> <span>print</span> <span>"we got an exception: %s"</span> % (<span>f</span>.<span>getTraceback</span>(),) <span>f</span>.<span>trap</span>(<span>RuntimeError</span>)
<span>def</span> <span>handleResult</span>(<span>result</span>): <span>Counter</span>.<span>num</span> += <span>1</span> <span>print</span> <span>"callback %s"</span> % (<span>Counter</span>.<span>num</span>,) <span>print</span> <span>"\tgot result: %s"</span> % (<span>result</span>,) <span>return</span> <span>"yay! handleResult was successful!"</span>
<span>def</span> <span>failAtHandlingResult</span>(<span>result</span>): <span>Counter</span>.<span>num</span> += <span>1</span> <span>print</span> <span>"callback %s"</span> % (<span>Counter</span>.<span>num</span>,) <span>print</span> <span>"\tgot result: %s"</span> % (<span>result</span>,) <span>print</span> <span>"\tabout to raise exception"</span> <span>raise</span> <span>RuntimeError</span>, <span>"whoops! we encountered an error"</span>
<span>def</span> <span>behindTheScenes</span>(<span>result</span>): <span>if</span> <span>not</span> <span>isinstance</span>(<span>result</span>, <span>failure</span>.<span>Failure</span>): <span># ---- callback</span> <span>try</span>: <span>result</span> = <span>handleResult</span>(<span>result</span>) <span>except</span>: <span>result</span> = <span>failure</span>.<span>Failure</span>() <span>else</span>: <span># ---- errback</span> <span>pass</span>
<span>if</span> <span>not</span> <span>isinstance</span>(<span>result</span>, <span>failure</span>.<span>Failure</span>): <span># ---- callback</span>
<span>pass</span>
<span>else</span>: <span># ---- errback</span>
<span>try</span>:
<span>result</span> = <span>handleFailure</span>(<span>result</span>)
<span>except</span>:
<span>result</span> = <span>failure</span>.<span>Failure</span>()
<span>def</span> <span>deferredExample</span>(<span>result</span>): <span>d</span> = <span>defer</span>.<span>Deferred</span>() <span>d</span>.<span>addCallback</span>(<span>handleResult</span>) <span>d</span>.<span>addCallback</span>(<span>failAtHandlingResult</span>) <span>d</span>.<span>addErrback</span>(<span>handleFailure</span>)
<span>d</span>.<span>errback</span>(<span>result</span>)
<span>if</span> <span>name</span> == <span>''main''</span>: <span>result</span> = <span>None</span> <span>try</span>: <span>raise</span> <span>RuntimeError</span>, <span>"doh! failure!"</span> <span>except</span>: <span>result</span> = <span>failure</span>.<span>Failure</span>() <span>behindTheScenes</span>(<span>result</span>) <span>print</span> <span>"\n-------------------------------------------------\n"</span> <span>Counter</span>.<span>num</span> = <span>0</span> <span>deferredExample</span>(<span>result</span>) </pre>
<div>Source listing - <a href="../listings/deferred/deferred_ex1a.py"><span>../listings/deferred/deferred_ex1a.py</span></a></div> </div> <pre> errback we got an exception: Traceback (most recent call last): --- exception caught here --- File "deferred_ex1a.py", line 73, in ? raise RuntimeError, "*doh*! failure!" exceptions.RuntimeError: *doh*! failure! </pre> <p>The important thing to note (as it will come up again in later examples) is that the callback isn''t touched, the failure goes right to the errback. Also note that the errback trap()s the expected exception type. If you don''t trap the exception, an error will be logged when the deferred is garbage-collected.</p> <p>值得注意的是(因为在后面的例子中还会碰到),callback根本没机会发言,failure直接走到errback那里去了。同样errback trap()(捕捉到了)它所希望得到的异常。如果你没有捕获异常,那么当垃圾回收器回收deferred的时候,它就会往日志里写一条error记录。</p>
<h3>Exceptions raised in callbacks<a name="auto4" id="auto4"></a></h3> <h3>callback抛出了异常</h3> <p>Now let''s see what happens when <em>our callback</em> raises an exception</p> <p>现在我们来看看当<em>callback</em>抛出异常的时候会发生些什么。</p> <div> <pre> <span>#!/usr/bin/python2.3 </span> <span>from</span> <span>twisted</span>.<span>internet</span> <span>import</span> <span>defer</span> <span>from</span> <span>twisted</span>.<span>python</span> <span>import</span> <span>failure</span>, <span>util</span>
<span>""" here we have a slightly more involved case. The deferred is called back with a result. the first callback returns a value, the second callback, however raises an exception, which is handled by the errback. """</span>
<span>class</span> <span>Counter</span>(<span>object</span>): <span>num</span> = <span>0</span>
<span>def</span> <span>handleFailure</span>(<span>f</span>): <span>print</span> <span>"errback"</span> <span>print</span> <span>"we got an exception: %s"</span> % (<span>f</span>.<span>getTraceback</span>(),) <span>f</span>.<span>trap</span>(<span>RuntimeError</span>)
<span>def</span> <span>handleResult</span>(<span>result</span>): <span>Counter</span>.<span>num</span> += <span>1</span> <span>print</span> <span>"callback %s"</span> % (<span>Counter</span>.<span>num</span>,) <span>print</span> <span>"\tgot result: %s"</span> % (<span>result</span>,) <span>return</span> <span>"yay! handleResult was successful!"</span>
<span>def</span> <span>failAtHandlingResult</span>(<span>result</span>): <span>Counter</span>.<span>num</span> += <span>1</span> <span>print</span> <span>"callback %s"</span> % (<span>Counter</span>.<span>num</span>,) <span>print</span> <span>"\tgot result: %s"</span> % (<span>result</span>,) <span>print</span> <span>"\tabout to raise exception"</span> <span>raise</span> <span>RuntimeError</span>, <span>"whoops! we encountered an error"</span>
<span>def</span> <span>behindTheScenes</span>(<span>result</span>): <span>if</span> <span>not</span> <span>isinstance</span>(<span>result</span>, <span>failure</span>.<span>Failure</span>): <span># ---- callback</span> <span>try</span>: <span>result</span> = <span>handleResult</span>(<span>result</span>) <span>except</span>: <span>result</span> = <span>failure</span>.<span>Failure</span>() <span>else</span>: <span># ---- errback</span> <span>pass</span>
<span>if</span> <span>not</span> <span>isinstance</span>(<span>result</span>, <span>failure</span>.<span>Failure</span>): <span># ---- callback</span>
<span>try</span>:
<span>result</span> = <span>failAtHandlingResult</span>(<span>result</span>)
<span>except</span>:
<span>result</span> = <span>failure</span>.<span>Failure</span>()
<span>else</span>: <span># ---- errback</span>
<span>pass</span>
<span>if</span> <span>not</span> <span>isinstance</span>(<span>result</span>, <span>failure</span>.<span>Failure</span>): <span># ---- callback</span>
<span>pass</span>
<span>else</span>: <span># ---- errback</span>
<span>try</span>:
<span>result</span> = <span>handleFailure</span>(<span>result</span>)
<span>except</span>:
<span>result</span> = <span>failure</span>.<span>Failure</span>()
<span>def</span> <span>deferredExample</span>(): <span>d</span> = <span>defer</span>.<span>Deferred</span>() <span>d</span>.<span>addCallback</span>(<span>handleResult</span>) <span>d</span>.<span>addCallback</span>(<span>failAtHandlingResult</span>) <span>d</span>.<span>addErrback</span>(<span>handleFailure</span>)
<span>d</span>.<span>callback</span>(<span>"success"</span>)
<span>if</span> <span>name</span> == <span>''main''</span>: <span>behindTheScenes</span>(<span>"success"</span>) <span>print</span> <span>"\n-------------------------------------------------\n"</span> <span>Counter</span>.<span>num</span> = <span>0</span> <span>deferredExample</span>() </pre>
<div>Source listing - <a href="../listings/deferred/deferred_ex1b.py"><span>../listings/deferred/deferred_ex1b.py</span></a></div> </div> <p>And the output: (note, tracebacks will be edited slightly to conserve space)</p> <pre> callback 1 got result: success callback 2 got result: yay! handleResult was successful! about to raise exception errback we got an exception: Traceback (most recent call last): --- <exception caught here> --- File "/home/slyphon/Projects/Twisted/trunk/twisted/internet/defer.py", line 326, in _runCallbacks self.result = callback(self.result, *args, **kw) File "./deferred_ex1.py", line 32, in failAtHandlingResult raise RuntimeError, "whoops! we encountered an error" exceptions.RuntimeError: whoops! we encountered an error </pre> <p>If your callback raises an exception, the next method to be called will be the next errback in your chain.</p> <p>如果callback抛出了异常,那么下一个调用的将是跟在这个callback之后的第一个errback。</p>
<h3>Exceptions will only be handled by errbacks<a name="auto5" id="auto5"></a></h3> <h3>只有errback才会去管Exception</h3>
<p>If a callback raises an exception the next method to be called will be next errback in the chain. If the chain is started off with a failure, the first method to be called will be the first errback.</p> <p>如果callback抛出了异常,那么下一个调用的将是跟在这个callabck后面的第一个errback。如果callback链一开始就出了错,那么它就会调用第一个errback。</p> <div> <pre> <span>#!/usr/bin/python2.3 </span> <span>from</span> <span>twisted</span>.<span>internet</span> <span>import</span> <span>defer</span> <span>from</span> <span>twisted</span>.<span>python</span> <span>import</span> <span>failure</span>, <span>util</span>
<span>""" this example shows an important concept that many deferred newbies (myself included) have trouble understanding.
when an error occurs in a callback, the first errback after the error occurs will be the next method called. (in the next example we''ll see what happens in the ''chain'' after an errback)
"""</span>
<span>class</span> <span>Counter</span>(<span>object</span>): <span>num</span> = <span>0</span>
<span>def</span> <span>handleFailure</span>(<span>f</span>): <span>print</span> <span>"errback"</span> <span>print</span> <span>"we got an exception: %s"</span> % (<span>f</span>.<span>getTraceback</span>(),) <span>f</span>.<span>trap</span>(<span>RuntimeError</span>)
<span>def</span> <span>handleResult</span>(<span>result</span>): <span>Counter</span>.<span>num</span> += <span>1</span> <span>print</span> <span>"callback %s"</span> % (<span>Counter</span>.<span>num</span>,) <span>print</span> <span>"\tgot result: %s"</span> % (<span>result</span>,) <span>return</span> <span>"yay! handleResult was successful!"</span>
<span>def</span> <span>failAtHandlingResult</span>(<span>result</span>): <span>Counter</span>.<span>num</span> += <span>1</span> <span>print</span> <span>"callback %s"</span> % (<span>Counter</span>.<span>num</span>,) <span>print</span> <span>"\tgot result: %s"</span> % (<span>result</span>,) <span>print</span> <span>"\tabout to raise exception"</span> <span>raise</span> <span>RuntimeError</span>, <span>"whoops! we encountered an error"</span>
<span>def</span> <span>behindTheScenes</span>(<span>result</span>): <span># equivalent to d.callback(result) </span> <span># now, let''s make the error happen in the first callback </span> <span>if</span> <span>not</span> <span>isinstance</span>(<span>result</span>, <span>failure</span>.<span>Failure</span>): <span># ---- callback</span> <span>try</span>: <span>result</span> = <span>failAtHandlingResult</span>(<span>result</span>) <span>except</span>: <span>result</span> = <span>failure</span>.<span>Failure</span>() <span>else</span>: <span># ---- errback</span> <span>pass</span>
<span># note: this callback will be skipped because
</span> <span># result is a failure </span> <span>if</span> <span>not</span> <span>isinstance</span>(<span>result</span>, <span>failure</span>.<span>Failure</span>): <span># ---- callback</span> <span>try</span>: <span>result</span> = <span>handleResult</span>(<span>result</span>) <span>except</span>: <span>result</span> = <span>failure</span>.<span>Failure</span>() <span>else</span>: <span># ---- errback</span> <span>pass</span>
<span>if</span> <span>not</span> <span>isinstance</span>(<span>result</span>, <span>failure</span>.<span>Failure</span>): <span># ---- callback</span>
<span>pass</span>
<span>else</span>: <span># ---- errback</span>
<span>try</span>:
<span>result</span> = <span>handleFailure</span>(<span>result</span>)
<span>except</span>:
<span>result</span> = <span>failure</span>.<span>Failure</span>()
<span>def</span> <span>deferredExample</span>(): <span>d</span> = <span>defer</span>.<span>Deferred</span>() <span>d</span>.<span>addCallback</span>(<span>failAtHandlingResult</span>) <span>d</span>.<span>addCallback</span>(<span>handleResult</span>) <span>d</span>.<span>addErrback</span>(<span>handleFailure</span>)
<span>d</span>.<span>callback</span>(<span>"success"</span>)
<span>if</span> <span>name</span> == <span>''main''</span>: <span>behindTheScenes</span>(<span>"success"</span>) <span>print</span> <span>"\n-------------------------------------------------\n"</span> <span>Counter</span>.<span>num</span> = <span>0</span> <span>deferredExample</span>() </pre>
<div>Source listing - <a href="../listings/deferred/deferred_ex2.py"><span>../listings/deferred/deferred_ex2.py</span></a></div> </div> <pre> callback 1 got result: success about to raise exception errback we got an exception: Traceback (most recent call last): File "./deferred_ex2.py", line 85, in ? nonDeferredExample("success") --- <exception caught here> --- File "./deferred_ex2.py", line 46, in nonDeferredExample result = failAtHandlingResult(result) File "./deferred_ex2.py", line 35, in failAtHandlingResult raise RuntimeError, "whoops! we encountered an error" exceptions.RuntimeError: whoops! we encountered an error </pre> <p>You can see that our second callback, handleResult was not called because failAtHandlingResult raised an exception</p> <h3>Handling an exception and continuing on<a name="auto6" id="auto6"></a></h3> <h3>处理异常,然后继续</h3> <p>In this example, we see an errback handle an exception raised in the preceeding callback. Take note that it could just as easily been an exception from <strong>any other</strong> preceeding method. You''ll see that after the exception is handled in the errback (i.e. the errback does not return a failure or raise an exception) the chain continues on with the next callback.</p> <p>在这个例子里,errback将会处理由上一个callback所抛出的一样。其实这个异常可以是<strong>任意</strong>一个callback所产生的。你会发现当errback处理完异常之后(比方说errback不再返回failure或者抛出异常),callback链会继续下一个callback。</p> <div> <pre> <span>#!/usr/bin/python2.3 </span> <span>from</span> <span>twisted</span>.<span>internet</span> <span>import</span> <span>defer</span> <span>from</span> <span>twisted</span>.<span>python</span> <span>import</span> <span>failure</span>, <span>util</span>
<span>""" now we see how an errback can handle errors. if an errback does not raise an exception, the next callback in the chain will be called
"""</span>
<span>class</span> <span>Counter</span>(<span>object</span>): <span>num</span> = <span>0</span>
<span>def</span> <span>handleFailure</span>(<span>f</span>): <span>print</span> <span>"errback"</span> <span>print</span> <span>"we got an exception: %s"</span> % (<span>f</span>.<span>getTraceback</span>(),) <span>f</span>.<span>trap</span>(<span>RuntimeError</span>) <span>return</span> <span>"okay, continue on"</span>
<span>def</span> <span>handleResult</span>(<span>result</span>): <span>Counter</span>.<span>num</span> += <span>1</span> <span>print</span> <span>"callback %s"</span> % (<span>Counter</span>.<span>num</span>,) <span>print</span> <span>"\tgot result: %s"</span> % (<span>result</span>,) <span>return</span> <span>"yay! handleResult was successful!"</span>
<span>def</span> <span>failAtHandlingResult</span>(<span>result</span>): <span>Counter</span>.<span>num</span> += <span>1</span> <span>print</span> <span>"callback %s"</span> % (<span>Counter</span>.<span>num</span>,) <span>print</span> <span>"\tgot result: %s"</span> % (<span>result</span>,) <span>print</span> <span>"\tabout to raise exception"</span> <span>raise</span> <span>RuntimeError</span>, <span>"whoops! we encountered an error"</span>
<span>def</span> <span>callbackAfterErrback</span>(<span>result</span>): <span>Counter</span>.<span>num</span> += <span>1</span> <span>print</span> <span>"callback %s"</span> % (<span>Counter</span>.<span>num</span>,) <span>print</span> <span>"\tgot result: %s"</span> % (<span>result</span>,)
<span>def</span> <span>behindTheScenes</span>(<span>result</span>): <span># equivalent to d.callback(result) </span> <span>if</span> <span>not</span> <span>isinstance</span>(<span>result</span>, <span>failure</span>.<span>Failure</span>): <span># ---- callback</span> <span>try</span>: <span>result</span> = <span>handleResult</span>(<span>result</span>) <span>except</span>: <span>result</span> = <span>failure</span>.<span>Failure</span>() <span>else</span>: <span># ---- errback</span> <span>pass</span>
<span>if</span> <span>not</span> <span>isinstance</span>(<span>result</span>, <span>failure</span>.<span>Failure</span>): <span># ---- callback</span>
<span>try</span>:
<span>result</span> = <span>failAtHandlingResult</span>(<span>result</span>)
<span>except</span>:
<span>result</span> = <span>failure</span>.<span>Failure</span>()
<span>else</span>: <span># ---- errback</span>
<span>pass</span>
<span>if</span> <span>not</span> <span>isinstance</span>(<span>result</span>, <span>failure</span>.<span>Failure</span>): <span># ---- callback</span>
<span>pass</span>
<span>else</span>: <span># ---- errback</span>
<span>try</span>:
<span>result</span> = <span>handleFailure</span>(<span>result</span>)
<span>except</span>:
<span>result</span> = <span>failure</span>.<span>Failure</span>()
<span>if</span> <span>not</span> <span>isinstance</span>(<span>result</span>, <span>failure</span>.<span>Failure</span>): <span># ---- callback</span>
<span>try</span>:
<span>result</span> = <span>callbackAfterErrback</span>(<span>result</span>)
<span>except</span>:
<span>result</span> = <span>failure</span>.<span>Failure</span>()
<span>else</span>: <span># ---- errback</span>
<span>pass</span>
<span>def</span> <span>deferredExample</span>(): <span>d</span> = <span>defer</span>.<span>Deferred</span>() <span>d</span>.<span>addCallback</span>(<span>handleResult</span>) <span>d</span>.<span>addCallback</span>(<span>failAtHandlingResult</span>) <span>d</span>.<span>addErrback</span>(<span>handleFailure</span>) <span>d</span>.<span>addCallback</span>(<span>callbackAfterErrback</span>)
<span>d</span>.<span>callback</span>(<span>"success"</span>)
<span>if</span> <span>name</span> == <span>''main''</span>: <span>behindTheScenes</span>(<span>"success"</span>) <span>print</span> <span>"\n-------------------------------------------------\n"</span> <span>Counter</span>.<span>num</span> = <span>0</span> <span>deferredExample</span>() </pre>
<div>Source listing - <a href="../listings/deferred/deferred_ex3.py"><span>../listings/deferred/deferred_ex3.py</span></a></div> </div> <pre> callback 1 got result: success about to raise exception errback we got an exception: Traceback (most recent call last): --- <exception caught here> --- File "/home/slyphon/Projects/Twisted/trunk/twisted/internet/defer.py", line 326, in _runCallbacks self.result = callback(self.result, *args, **kw) File "./deferred_ex2.py", line 35, in failAtHandlingResult raise RuntimeError, "whoops! we encountered an error" exceptions.RuntimeError: whoops! we encountered an error </pre> <h2>addBoth: the deferred version of <em>finally</em><a name="auto7" id="auto7"></a></h2> <h2>addBoth:deferred版的<em>finally</em></h2> <p>Now we see how deferreds do <strong>finally</strong>, with .addBoth. The callback that gets added as addBoth will be called if the result is a failure or non-failure. We''ll also see in this example, that our doThisNoMatterWhat() method follows a common idiom in deferred callbacks by acting as a passthru, returning the value that it received to allow processing the chain to continue, but appearing transparent in terms of the result.</p> <p>现在我们来看看deferred是怎样实现<strong>finally</strong>的,答案就是.addBoth。不管参数是不是failure,addBoth所加载的callback都会被调用。此外我们还会看的,doThisNoMatterWhat()方法以充当passthru的方式遵守了deferred的callback约定。它将收到的数据原封不动地发出去,这样处理链就能继续下去了。对数据来说,它是完全透明的。</p>
<div> <pre> <span>#!/usr/bin/python2.3 </span> <span>from</span> <span>twisted</span>.<span>internet</span> <span>import</span> <span>defer</span> <span>from</span> <span>twisted</span>.<span>python</span> <span>import</span> <span>failure</span>, <span>util</span>
<span>""" now we''ll see what happens when you use ''addBoth''
"""</span>
<span>class</span> <span>Counter</span>(<span>object</span>): <span>num</span> = <span>0</span>
<span>def</span> <span>handleFailure</span>(<span>f</span>): <span>print</span> <span>"errback"</span> <span>print</span> <span>"we got an exception: %s"</span> % (<span>f</span>.<span>getTraceback</span>(),) <span>f</span>.<span>trap</span>(<span>RuntimeError</span>) <span>return</span> <span>"okay, continue on"</span>
<span>def</span> <span>handleResult</span>(<span>result</span>): <span>Counter</span>.<span>num</span> += <span>1</span> <span>print</span> <span>"callback %s"</span> % (<span>Counter</span>.<span>num</span>,) <span>print</span> <span>"\tgot result: %s"</span> % (<span>result</span>,) <span>return</span> <span>"yay! handleResult was successful!"</span>
<span>def</span> <span>failAtHandlingResult</span>(<span>result</span>): <span>Counter</span>.<span>num</span> += <span>1</span> <span>print</span> <span>"callback %s"</span> % (<span>Counter</span>.<span>num</span>,) <span>print</span> <span>"\tgot result: %s"</span> % (<span>result</span>,) <span>print</span> <span>"\tabout to raise exception"</span> <span>raise</span> <span>RuntimeError</span>, <span>"whoops! we encountered an error"</span>
<span>def</span> <span>doThisNoMatterWhat</span>(<span>arg</span>): <span>Counter</span>.<span>num</span> += <span>1</span> <span>print</span> <span>"both %s"</span> % (<span>Counter</span>.<span>num</span>,) <span>print</span> <span>"\tgot argument %r"</span> % (<span>arg</span>,) <span>print</span> <span>"\tdoing something very important"</span> <span># we pass the argument we received to the next phase here </span> <span>return</span> <span>arg</span>
<span>def</span> <span>behindTheScenes</span>(<span>result</span>): <span># equivalent to d.callback(result) </span> <span>if</span> <span>not</span> <span>isinstance</span>(<span>result</span>, <span>failure</span>.<span>Failure</span>): <span># ---- callback</span> <span>try</span>: <span>result</span> = <span>handleResult</span>(<span>result</span>) <span>except</span>: <span>result</span> = <span>failure</span>.<span>Failure</span>() <span>else</span>: <span># ---- errback</span> <span>pass</span>
<span>if</span> <span>not</span> <span>isinstance</span>(<span>result</span>, <span>failure</span>.<span>Failure</span>): <span># ---- callback</span>
<span>try</span>:
<span>result</span> = <span>failAtHandlingResult</span>(<span>result</span>)
<span>except</span>:
<span>result</span> = <span>failure</span>.<span>Failure</span>()
<span>else</span>: <span># ---- errback</span>
<span>pass</span>
<span># ---- this is equivalent to addBoth(doThisNoMatterWhat)
</span> <span>if</span> <span>not</span> <span>isinstance</span>(<span>result</span>, <span>failure</span>.<span>Failure</span>): <span>try</span>: <span>result</span> = <span>doThisNoMatterWhat</span>(<span>result</span>) <span>except</span>: <span>result</span> = <span>failure</span>.<span>Failure</span>() <span>else</span>: <span>try</span>: <span>result</span> = <span>doThisNoMatterWhat</span>(<span>result</span>) <span>except</span>: <span>result</span> = <span>failure</span>.<span>Failure</span>()
<span>if</span> <span>not</span> <span>isinstance</span>(<span>result</span>, <span>failure</span>.<span>Failure</span>): <span># ---- callback</span>
<span>pass</span>
<span>else</span>: <span># ---- errback</span>
<span>try</span>:
<span>result</span> = <span>handleFailure</span>(<span>result</span>)
<span>except</span>:
<span>result</span> = <span>failure</span>.<span>Failure</span>()
<span>def</span> <span>deferredExample</span>(): <span>d</span> = <span>defer</span>.<span>Deferred</span>() <span>d</span>.<span>addCallback</span>(<span>handleResult</span>) <span>d</span>.<span>addCallback</span>(<span>failAtHandlingResult</span>) <span>d</span>.<span>addBoth</span>(<span>doThisNoMatterWhat</span>) <span>d</span>.<span>addErrback</span>(<span>handleFailure</span>)
<span>d</span>.<span>callback</span>(<span>"success"</span>)
<span>if</span> <span>name</span> == <span>''main''</span>: <span>behindTheScenes</span>(<span>"success"</span>) <span>print</span> <span>"\n-------------------------------------------------\n"</span> <span>Counter</span>.<span>num</span> = <span>0</span> <span>deferredExample</span>() </pre>
<div>Source listing - <a href="../listings/deferred/deferred_ex4.py"><span>../listings/deferred/deferred_ex4.py</span></a></div> </div> <pre> callback 1 got result: success callback 2 got result: yay! handleResult was successful! about to raise exception both 3 got argument <twisted.python.failure.Failure exceptions.RuntimeError> doing something very important errback we got an exception: Traceback (most recent call last): --- <exception caught here> --- File "/home/slyphon/Projects/Twisted/trunk/twisted/internet/defer.py", line 326, in _runCallbacks self.result = callback(self.result, *args, **kw) File "./deferred_ex4.py", line 32, in failAtHandlingResult raise RuntimeError, "whoops! we encountered an error" exceptions.RuntimeError: whoops! we encountered an error </pre> <p>You can see that the errback is called, (and consequently, the failure is trapped). This is because doThisNoMatterWhat method returned the value it received, a failure.</p> <h2>addCallbacks: decision making based on previous success or failure<a name="auto8" id="auto8"></a></h2> <h2>addCallbacks: 根据前面的运行结果加载callback</h2> <p>As we''ve been seeing in the examples, the callback is a pair of callback/errback. Using addCallback or addErrback is actually a special case where one of the pair is a pass statement. If you want to make a decision based on whether or not the previous result in the chain was a failure or not (which is very rare, but included here for completeness), you use addCallbacks. Note that this is <strong>not</strong> the same thing as an addCallback followed by an addErrback.</p> <p>正如我们前面所讲的,回调函数是一组callback/errback。无论是addCallback还是addErrback其实都是特例,因为在加载一个函数的同时,我们也pass了另一个另一个函数。如果你想根据前一次调用是否成功来判断该加载哪个函数(这种情况十分罕见,不过出于完整性的考虑,twisted也提供了),那么可以使用addCallbacks。注意,这和addCallback之后再addErrback<strong>是两码事</strong></p>
<div> <pre> <span>#!/usr/bin/python2.3 </span> <span>from</span> <span>twisted</span>.<span>internet</span> <span>import</span> <span>defer</span> <span>from</span> <span>twisted</span>.<span>python</span> <span>import</span> <span>failure</span>, <span>util</span>
<span>""" now comes the more nuanced addCallbacks, which allows us to make a yes/no (branching) decision based on whether the result at a given point is a failure or not.
"""</span>
<span>class</span> <span>Counter</span>(<span>object</span>): <span>num</span> = <span>0</span>
<span>def</span> <span>handleFailure</span>(<span>f</span>): <span>print</span> <span>"errback"</span> <span>print</span> <span>"we got an exception: %s"</span> % (<span>f</span>.<span>getTraceback</span>(),) <span>f</span>.<span>trap</span>(<span>RuntimeError</span>) <span>return</span> <span>"okay, continue on"</span>
<span>def</span> <span>handleResult</span>(<span>result</span>): <span>Counter</span>.<span>num</span> += <span>1</span> <span>print</span> <span>"callback %s"</span> % (<span>Counter</span>.<span>num</span>,) <span>print</span> <span>"\tgot result: %s"</span> % (<span>result</span>,) <span>return</span> <span>"yay! handleResult was successful!"</span>
<span>def</span> <span>failAtHandlingResult</span>(<span>result</span>): <span>Counter</span>.<span>num</span> += <span>1</span> <span>print</span> <span>"callback %s"</span> % (<span>Counter</span>.<span>num</span>,) <span>print</span> <span>"\tgot result: %s"</span> % (<span>result</span>,) <span>print</span> <span>"\tabout to raise exception"</span> <span>raise</span> <span>RuntimeError</span>, <span>"whoops! we encountered an error"</span>
<span>def</span> <span>yesDecision</span>(<span>result</span>): <span>Counter</span>.<span>num</span> += <span>1</span> <span>print</span> <span>"yes decision %s"</span> % (<span>Counter</span>.<span>num</span>,) <span>print</span> <span>"\twasn''t a failure, so we can plow ahead"</span> <span>return</span> <span>"go ahead!"</span>
<span>def</span> <span>noDecision</span>(<span>result</span>): <span>Counter</span>.<span>num</span> += <span>1</span> <span>result</span>.<span>trap</span>(<span>RuntimeError</span>) <span>print</span> <span>"no decision %s"</span> % (<span>Counter</span>.<span>num</span>,) <span>print</span> <span>"\tdoh! a failure! quick! damage control!"</span> <span>return</span> <span>"damage control successful!"</span>
<span>def</span> <span>behindTheScenes</span>(<span>result</span>):
<span>if</span> <span>not</span> <span>isinstance</span>(<span>result</span>, <span>failure</span>.<span>Failure</span>): <span># ---- callback</span>
<span>try</span>:
<span>result</span> = <span>failAtHandlingResult</span>(<span>result</span>)
<span>except</span>:
<span>result</span> = <span>failure</span>.<span>Failure</span>()
<span>else</span>: <span># ---- errback</span>
<span>pass</span>
<span># this is equivalent to addCallbacks(yesDecision, noDecision)
</span> <span>if</span> <span>not</span> <span>isinstance</span>(<span>result</span>, <span>failure</span>.<span>Failure</span>): <span># ---- callback</span> <span>try</span>: <span>result</span> = <span>yesDecision</span>(<span>result</span>) <span>except</span>: <span>result</span> = <span>failure</span>.<span>Failure</span>() <span>else</span>: <span># ---- errback</span> <span>try</span>: <span>result</span> = <span>noDecision</span>(<span>result</span>) <span>except</span>: <span>result</span> = <span>failure</span>.<span>Failure</span>()
<span>if</span> <span>not</span> <span>isinstance</span>(<span>result</span>, <span>failure</span>.<span>Failure</span>): <span># ---- callback</span>
<span>try</span>:
<span>result</span> = <span>handleResult</span>(<span>result</span>)
<span>except</span>:
<span>result</span> = <span>failure</span>.<span>Failure</span>()
<span>else</span>: <span># ---- errback</span>
<span>pass</span>
<span># this is equivalent to addCallbacks(yesDecision, noDecision)
</span> <span>if</span> <span>not</span> <span>isinstance</span>(<span>result</span>, <span>failure</span>.<span>Failure</span>): <span># ---- callback</span> <span>try</span>: <span>result</span> = <span>yesDecision</span>(<span>result</span>) <span>except</span>: <span>result</span> = <span>failure</span>.<span>Failure</span>() <span>else</span>: <span># ---- errback</span> <span>try</span>: <span>result</span> = <span>noDecision</span>(<span>result</span>) <span>except</span>: <span>result</span> = <span>failure</span>.<span>Failure</span>()
<span>if</span> <span>not</span> <span>isinstance</span>(<span>result</span>, <span>failure</span>.<span>Failure</span>): <span># ---- callback</span>
<span>try</span>:
<span>result</span> = <span>handleResult</span>(<span>result</span>)
<span>except</span>:
<span>result</span> = <span>failure</span>.<span>Failure</span>()
<span>else</span>: <span># ---- errback</span>
<span>pass</span>
<span>if</span> <span>not</span> <span>isinstance</span>(<span>result</span>, <span>failure</span>.<span>Failure</span>): <span># ---- callback</span>
<span>pass</span>
<span>else</span>: <span># ---- errback</span>
<span>try</span>:
<span>result</span> = <span>handleFailure</span>(<span>result</span>)
<span>except</span>:
<span>result</span> = <span>failure</span>.<span>Failure</span>()
<span>def</span> <span>deferredExample</span>(): <span>d</span> = <span>defer</span>.<span>Deferred</span>() <span>d</span>.<span>addCallback</span>(<span>failAtHandlingResult</span>) <span>d</span>.<span>addCallbacks</span>(<span>yesDecision</span>, <span>noDecision</span>) <span># noDecision will be called</span> <span>d</span>.<span>addCallback</span>(<span>handleResult</span>) <span># - A -</span> <span>d</span>.<span>addCallbacks</span>(<span>yesDecision</span>, <span>noDecision</span>) <span># yesDecision will be called</span> <span>d</span>.<span>addCallback</span>(<span>handleResult</span>) <span>d</span>.<span>addErrback</span>(<span>handleFailure</span>)
<span>d</span>.<span>callback</span>(<span>"success"</span>)
<span>if</span> <span>name</span> == <span>''main''</span>: <span>behindTheScenes</span>(<span>"success"</span>) <span>print</span> <span>"\n-------------------------------------------------\n"</span> <span>Counter</span>.<span>num</span> = <span>0</span> <span>deferredExample</span>() </pre>
<div>Source listing - <a href="../listings/deferred/deferred_ex5.py"><span>../listings/deferred/deferred_ex5.py</span></a></div> </div> <pre> callback 1 got result: success about to raise exception no decision 2 *doh*! a failure! quick! damage control! callback 3 got result: damage control successful! yes decision 4 wasn''t a failure, so we can plow ahead callback 5 got result: go ahead! </pre> <p>Notice that our errback is never called. The noDecision method returns a non-failure so processing continues with the next callback. If we wanted to skip the callback at "- A -" because of the error, but do some kind of processing in response to the error, we would have used a passthru, and returned the failure we received, as we see in this next example:</p> <p>注意,我们的errback一直没被调用。noDecision方法返回了一个非failure的值,所以处理链接下来调用的是callback。如果你想跳过位于"- A -"的callback,但又不想放过错误,那么你就得用passthru把收到的failure再发出去。这就是下一段例程所演示的:</p> <div> <pre> <span>#!/usr/bin/python2.3 </span> <span>from</span> <span>twisted</span>.<span>internet</span> <span>import</span> <span>defer</span> <span>from</span> <span>twisted</span>.<span>python</span> <span>import</span> <span>failure</span>, <span>util</span>
<span>""" now comes the more nuanced addCallbacks, which allows us to make a yes/no (branching) decision based on whether the result at a given point is a failure or not.
here, we return the failure from noDecisionPassthru, the errback argument to the first addCallbacks method invocation, and see what happens
"""</span>
<span>class</span> <span>Counter</span>(<span>object</span>): <span>num</span> = <span>0</span>
<span>def</span> <span>handleFailure</span>(<span>f</span>): <span>print</span> <span>"errback"</span> <span>print</span> <span>"we got an exception: %s"</span> % (<span>f</span>.<span>getTraceback</span>(),) <span>f</span>.<span>trap</span>(<span>RuntimeError</span>) <span>return</span> <span>"okay, continue on"</span>
<span>def</span> <span>handleResult</span>(<span>result</span>): <span>Counter</span>.<span>num</span> += <span>1</span> <span>print</span> <span>"callback %s"</span> % (<span>Counter</span>.<span>num</span>,) <span>print</span> <span>"\tgot result: %s"</span> % (<span>result</span>,) <span>return</span> <span>"yay! handleResult was successful!"</span>
<span>def</span> <span>failAtHandlingResult</span>(<span>result</span>): <span>Counter</span>.<span>num</span> += <span>1</span> <span>print</span> <span>"callback %s"</span> % (<span>Counter</span>.<span>num</span>,) <span>print</span> <span>"\tgot result: %s"</span> % (<span>result</span>,) <span>print</span> <span>"\tabout to raise exception"</span> <span>raise</span> <span>RuntimeError</span>, <span>"whoops! we encountered an error"</span>
<span>def</span> <span>yesDecision</span>(<span>result</span>): <span>Counter</span>.<span>num</span> += <span>1</span> <span>print</span> <span>"yes decision %s"</span> % (<span>Counter</span>.<span>num</span>,) <span>print</span> <span>"\twasn''t a failure, so we can plow ahead"</span> <span>return</span> <span>"go ahead!"</span>
<span>def</span> <span>noDecision</span>(<span>result</span>): <span>Counter</span>.<span>num</span> += <span>1</span> <span>result</span>.<span>trap</span>(<span>RuntimeError</span>) <span>print</span> <span>"no decision %s"</span> % (<span>Counter</span>.<span>num</span>,) <span>print</span> <span>"\tdoh! a failure! quick! damage control!"</span> <span>return</span> <span>"damage control successful!"</span>
<span>def</span> <span>noDecisionPassthru</span>(<span>result</span>): <span>Counter</span>.<span>num</span> += <span>1</span> <span>print</span> <span>"no decision %s"</span> % (<span>Counter</span>.<span>num</span>,) <span>print</span> <span>"\tdoh! a failure! don''t know what to do, returning failure!"</span> <span>return</span> <span>result</span>
<span>def</span> <span>behindTheScenes</span>(<span>result</span>):
<span>if</span> <span>not</span> <span>isinstance</span>(<span>result</span>, <span>failure</span>.<span>Failure</span>): <span># ---- callback</span>
<span>try</span>:
<span>result</span> = <span>failAtHandlingResult</span>(<span>result</span>)
<span>except</span>:
<span>result</span> = <span>failure</span>.<span>Failure</span>()
<span>else</span>: <span># ---- errback</span>
<span>pass</span>
<span># this is equivalent to addCallbacks(yesDecision, noDecision)
</span> <span>if</span> <span>not</span> <span>isinstance</span>(<span>result</span>, <span>failure</span>.<span>Failure</span>): <span># ---- callback</span> <span>try</span>: <span>result</span> = <span>yesDecision</span>(<span>result</span>) <span>except</span>: <span>result</span> = <span>failure</span>.<span>Failure</span>() <span>else</span>: <span># ---- errback</span> <span>try</span>: <span>result</span> = <span>noDecisionPassthru</span>(<span>result</span>) <span>except</span>: <span>result</span> = <span>failure</span>.<span>Failure</span>()
<span>if</span> <span>not</span> <span>isinstance</span>(<span>result</span>, <span>failure</span>.<span>Failure</span>): <span># ---- callback</span>
<span>try</span>:
<span>result</span> = <span>handleResult</span>(<span>result</span>)
<span>except</span>:
<span>result</span> = <span>failure</span>.<span>Failure</span>()
<span>else</span>: <span># ---- errback</span>
<span>pass</span>
<span># this is equivalent to addCallbacks(yesDecision, noDecision)
</span> <span>if</span> <span>not</span> <span>isinstance</span>(<span>result</span>, <span>failure</span>.<span>Failure</span>): <span># ---- callback</span> <span>try</span>: <span>result</span> = <span>yesDecision</span>(<span>result</span>) <span>except</span>: <span>result</span> = <span>failure</span>.<span>Failure</span>() <span>else</span>: <span># ---- errback</span> <span>try</span>: <span>result</span> = <span>noDecision</span>(<span>result</span>) <span>except</span>: <span>result</span> = <span>failure</span>.<span>Failure</span>()
<span>if</span> <span>not</span> <span>isinstance</span>(<span>result</span>, <span>failure</span>.<span>Failure</span>): <span># ---- callback</span>
<span>try</span>:
<span>result</span> = <span>handleResult</span>(<span>result</span>)
<span>except</span>:
<span>result</span> = <span>failure</span>.<span>Failure</span>()
<span>else</span>: <span># ---- errback</span>
<span>pass</span>
<span>if</span> <span>not</span> <span>isinstance</span>(<span>result</span>, <span>failure</span>.<span>Failure</span>): <span># ---- callback</span>
<span>pass</span>
<span>else</span>: <span># ---- errback</span>
<span>try</span>:
<span>result</span> = <span>handleFailure</span>(<span>result</span>)
<span>except</span>:
<span>result</span> = <span>failure</span>.<span>Failure</span>()
<span>def</span> <span>deferredExample</span>(): <span>d</span> = <span>defer</span>.<span>Deferred</span>() <span>d</span>.<span>addCallback</span>(<span>failAtHandlingResult</span>)
<span># noDecisionPassthru will be called
</span> <span>d</span>.<span>addCallbacks</span>(<span>yesDecision</span>, <span>noDecisionPassthru</span>) <span>d</span>.<span>addCallback</span>(<span>handleResult</span>) <span># - A -</span>
<span># noDecision will be called
</span> <span>d</span>.<span>addCallbacks</span>(<span>yesDecision</span>, <span>noDecision</span>) <span>d</span>.<span>addCallback</span>(<span>handleResult</span>) <span># - B -</span> <span>d</span>.<span>addErrback</span>(<span>handleFailure</span>)
<span>d</span>.<span>callback</span>(<span>"success"</span>)
<span>if</span> <span>name</span> == <span>''main''</span>: <span>behindTheScenes</span>(<span>"success"</span>) <span>print</span> <span>"\n-------------------------------------------------\n"</span> <span>Counter</span>.<span>num</span> = <span>0</span> <span>deferredExample</span>() </pre>
<div>Source listing - <a href="../listings/deferred/deferred_ex6.py"><span>../listings/deferred/deferred_ex6.py</span></a></div> </div> <pre> callback 1 got result: success about to raise exception no decision 2 *doh*! a failure! don''t know what to do, returning failure! no decision 3 *doh*! a failure! quick! damage control! callback 4 got result: damage control successful! </pre> <p>Two things to note here. First, "- A -" was skipped, like we wanted it to, and the second thing is that after "- A -", noDecision is called, because <strong>it is the next errback that exists in the chain</strong>. It returns a non-failure, so processing continues with the next callback at "- B -", and the errback at the end of the chain is never called</p> <p>有两点值得注意。第一,正如我们所希望的,它跳过了“- A -”,第二,跳过“- A -”之后它调用了noDecision,因为<strong>这是链中的下一个errback</strong>。这个errback返回的是一个非failure的值,所以接下来执行的是“- B -”的callback,而最有一个errback是不可能被调到的。</p>
<h2>Hints, tips, common mistakes, and miscellaney<a name="auto9" id="auto9"></a></h2> <h2>提示,技巧,常见错误及其它</h2> <h3>The deferred callback chain is stateful<a name="auto10" id="auto10"></a></h3> <h3>deffered的callback链是带状态的</h3> <p>A deferred that has been called back will call it''s addCallback and addErrback methods as appropriate in the order they are added, when they are added. So we see in the following example, deferredExample1 and deferredExample2 are equivalent. The first sets up the processing chain beforehand and then executes it, the other executes the chain as it is being constructed. This is because deferreds are <em>stateful</em>.</p> <p>deferred的回调顺序就是addCallback和addErrback的顺序。所以我们看下面这个例子,deferredExample1和deferredExample2是一样的。第一个先建处理链再调用,第二个则一边建一边调用。这是因为deferred是<em>带状态的</em>。</p>
<div> <pre> <span>#!/usr/bin/python2.3 </span> <span>from</span> <span>twisted</span>.<span>internet</span> <span>import</span> <span>defer</span> <span>from</span> <span>twisted</span>.<span>python</span> <span>import</span> <span>failure</span>, <span>util</span>
<span>""" The deferred callback chain is stateful, and can be executed before or after all callbacks have been added to the chain """</span>
<span>class</span> <span>Counter</span>(<span>object</span>): <span>num</span> = <span>0</span>
<span>def</span> <span>handleFailure</span>(<span>f</span>): <span>print</span> <span>"errback"</span> <span>print</span> <span>"we got an exception: %s"</span> % (<span>f</span>.<span>getTraceback</span>(),) <span>f</span>.<span>trap</span>(<span>RuntimeError</span>)
<span>def</span> <span>handleResult</span>(<span>result</span>): <span>Counter</span>.<span>num</span> += <span>1</span> <span>print</span> <span>"callback %s"</span> % (<span>Counter</span>.<span>num</span>,) <span>print</span> <span>"\tgot result: %s"</span> % (<span>result</span>,) <span>return</span> <span>"yay! handleResult was successful!"</span>
<span>def</span> <span>failAtHandlingResult</span>(<span>result</span>): <span>Counter</span>.<span>num</span> += <span>1</span> <span>print</span> <span>"callback %s"</span> % (<span>Counter</span>.<span>num</span>,) <span>print</span> <span>"\tgot result: %s"</span> % (<span>result</span>,) <span>print</span> <span>"\tabout to raise exception"</span> <span>raise</span> <span>RuntimeError</span>, <span>"whoops! we encountered an error"</span>
<span>def</span> <span>deferredExample1</span>(): <span># this is another common idiom, since all add* methods </span> <span># return the deferred instance, you can just chain your </span> <span># calls to addCallback and addErrback </span> <span>d</span> = <span>defer</span>.<span>Deferred</span>().<span>addCallback</span>(<span>failAtHandlingResult</span> ).<span>addCallback</span>(<span>handleResult</span> ).<span>addErrback</span>(<span>handleFailure</span>)
<span>d</span>.<span>callback</span>(<span>"success"</span>)
<span>def</span> <span>deferredExample2</span>(): <span>d</span> = <span>defer</span>.<span>Deferred</span>()
<span>d</span>.<span>callback</span>(<span>"success"</span>)
<span>d</span>.<span>addCallback</span>(<span>failAtHandlingResult</span>)
<span>d</span>.<span>addCallback</span>(<span>handleResult</span>)
<span>d</span>.<span>addErrback</span>(<span>handleFailure</span>)
<span>if</span> <span>name</span> == <span>''main''</span>: <span>deferredExample1</span>() <span>print</span> <span>"\n-------------------------------------------------\n"</span> <span>Counter</span>.<span>num</span> = <span>0</span> <span>deferredExample2</span>() </pre>
<div>Source listing - <a href="../listings/deferred/deferred_ex7.py"><span>../listings/deferred/deferred_ex7.py</span></a></div> </div> <pre> callback 1 got result: success about to raise exception errback we got an exception: Traceback (most recent call last): --- <exception caught here> --- File "/home/slyphon/Projects/Twisted/trunk/twisted/internet/defer.py", line 326, in _runCallbacks self.result = callback(self.result, *args, **kw) File "./deferred_ex7.py", line 35, in failAtHandlingResult raise RuntimeError, "whoops! we encountered an error" exceptions.RuntimeError: whoops! we encountered an error
callback 1 got result: success about to raise exception errback we got an exception: Traceback (most recent call last): --- <exception caught here> --- File "/home/slyphon/Projects/Twisted/trunk/twisted/internet/defer.py", line 326, in _runCallbacks self.result = callback(self.result, *args, **kw) File "./deferred_ex7.py", line 35, in failAtHandlingResult raise RuntimeError, "whoops! we encountered an error" exceptions.RuntimeError: whoops! we encountered an error </pre>
<p>This example also shows you the common idiom of chaining calls to addCallback and addErrback.</p> <h3>Don''t call .callback() on deferreds you didn''t create!<a name="auto11" id="auto11"></a></h3> <h3>别去调用还没建好的deferred的.callback()方法</h3> <p>It is an error to reinvoke deferreds callback or errback method, therefore if you didn''t create a deferred, <strong>do not under any circumstances</strong> call its callback or errback. doing so will raise an exception</p> <p>重复调用deferred的callback或errback办法是一种错误,所以如果你还没建好deferred,那就<strong>别去调用</strong>它的callback或errback,这么做只会导致错误。</p> <h3>Callbacks can return deferreds<a name="auto12" id="auto12"></a></h3> <h3>callback能返回deferred</h3> <p>If you need to call a method that returns a deferred within your callback chain, just return that deferred, and the result of the secondary deferred''s processing chain will become the result that gets passed to the next callback of the primary deferreds processing chain</p> <p>如果callback链里的方法会返回deferred,那就让它返回deferred。这个deferred的处理结果会被当作参数传给当前这个deferred的下一个callback。</p>
<div> <pre> <span>#!/usr/bin/python2.3 </span> <span>from</span> <span>twisted</span>.<span>internet</span> <span>import</span> <span>defer</span> <span>from</span> <span>twisted</span>.<span>python</span> <span>import</span> <span>failure</span>, <span>util</span>
<span>""" """</span>
<span>class</span> <span>Counter</span>(<span>object</span>): <span>num</span> = <span>0</span> <span>let</span> = <span>''a''</span>
<span>def</span> <span>incrLet</span>(<span>cls</span>):
<span>cls</span>.<span>let</span> = <span>chr</span>(<span>ord</span>(<span>cls</span>.<span>let</span>) + <span>1</span>)
<span>incrLet</span> = <span>classmethod</span>(<span>incrLet</span>)
<span>def</span> <span>handleFailure</span>(<span>f</span>): <span>print</span> <span>"errback"</span> <span>print</span> <span>"we got an exception: %s"</span> % (<span>f</span>.<span>getTraceback</span>(),) <span>return</span> <span>f</span>
<span>def</span> <span>subCb_B</span>(<span>result</span>): <span>print</span> <span>"sub-callback %s"</span> % (<span>Counter</span>.<span>let</span>,) <span>Counter</span>.<span>incrLet</span>() <span>s</span> = <span>" beautiful!"</span> <span>print</span> <span>"\tadding %r to result"</span> % (<span>s</span>,) <span>result</span> += <span>s</span> <span>return</span> <span>result</span>
<span>def</span> <span>subCb_A</span>(<span>result</span>): <span>print</span> <span>"sub-callback %s"</span> % (<span>Counter</span>.<span>let</span>,) <span>Counter</span>.<span>incrLet</span>() <span>s</span> = <span>" are "</span> <span>print</span> <span>"\tadding %r to result"</span> % (<span>s</span>,) <span>result</span> += <span>s</span> <span>return</span> <span>result</span>
<span>def</span> <span>mainCb_1</span>(<span>result</span>): <span>Counter</span>.<span>num</span> += <span>1</span> <span>print</span> <span>"callback %s"</span> % (<span>Counter</span>.<span>num</span>,) <span>print</span> <span>"\tgot result: %s"</span> % (<span>result</span>,) <span>result</span> += <span>" Deferreds "</span>
<span>d</span> = <span>defer</span>.<span>Deferred</span>().<span>addCallback</span>(<span>subCb_A</span>
).<span>addCallback</span>(<span>subCb_B</span>)
<span>d</span>.<span>callback</span>(<span>result</span>)
<span>return</span> <span>d</span>
<span>def</span> <span>mainCb_2</span>(<span>result</span>): <span>Counter</span>.<span>num</span> += <span>1</span> <span>print</span> <span>"callback %s"</span> % (<span>Counter</span>.<span>num</span>,) <span>print</span> <span>"\tgot result: %s"</span> % (<span>result</span>,)
<span>def</span> <span>deferredExample</span>(): <span>d</span> = <span>defer</span>.<span>Deferred</span>().<span>addCallback</span>(<span>mainCb_1</span> ).<span>addCallback</span>(<span>mainCb_2</span>)
<span>d</span>.<span>callback</span>(<span>"I hope you''ll agree: "</span>)
<span>if</span> <span>name</span> == <span>''main''</span>: <span>deferredExample</span>() </pre>
<div>Source listing - <a href="../listings/deferred/deferred_ex8.py"><span>../listings/deferred/deferred_ex8.py</span></a></div> </div> <pre> callback 1 got result: I hope you''ll agree: sub-callback a adding '' are '' to result sub-callback b adding '' beautiful!'' to result callback 2 got result: I hope you''ll agree: Deferreds are beautiful! </pre> <h2>Conclusion<a name="auto13" id="auto13"></a></h2> <h2>结论</h2> <p>Deferreds can be confusing, but only because they''re so elegant and simple. There is a lot of logical power that can expressed with a deferred''s processing chain, and once you see what''s going on behind the curtain, it''s a lot easier to understand how to make use of what deferreds have to offer.</p> </div> <p><a href="../howto/index.html">Index</a></p> <span>Version: 2.0.0</span> </body> </html>
Python Twisted pip软件包与Python3不兼容
如何解决Python Twisted pip软件包与Python3不兼容?
我正在尝试使用扭曲名称创建权威服务器。我使用的是python 3.6,并使用pip3 install twisted
安装,但是pip似乎没有使用python3版本进行更新。具体来说,pip具有twisted 20.3,但是20.3是为Python2编写的。文件authority.py
在20.3版本-Line 308中使用python2语法。关于何时更新pip包有任何想法吗?是否建议使用python2(和20.3版)或通过克隆存储库从源代码进行安装?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)
今天关于Python Twisted代理-如何拦截数据包和python拦截tcp数据包的分享就到这里,希望大家有所收获,若想了解更多关于pip安装提示Twisted错误问题(Python3.6.4安装Twisted错、Python 2.7 安装twisted、python twisted deferred、Python Twisted pip软件包与Python3不兼容等相关知识,可以在本站进行查询。
本文标签: