﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>IT博客-PYTHON爱好者-随笔分类-Python</title><link>http://www.cnitblog.com/donne/category/6611.html</link><description>PYTHON, twisted, 网络编程。</description><language>zh-cn</language><lastBuildDate>Thu, 17 Nov 2011 09:38:10 GMT</lastBuildDate><pubDate>Thu, 17 Nov 2011 09:38:10 GMT</pubDate><ttl>60</ttl><item><title>Twisted中启动子进程及进程间通信方式</title><link>http://www.cnitblog.com/donne/archive/2011/11/16/76327.html</link><dc:creator>Don Li</dc:creator><author>Don Li</author><pubDate>Wed, 16 Nov 2011 08:32:00 GMT</pubDate><guid>http://www.cnitblog.com/donne/archive/2011/11/16/76327.html</guid><wfw:comment>http://www.cnitblog.com/donne/comments/76327.html</wfw:comment><comments>http://www.cnitblog.com/donne/archive/2011/11/16/76327.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/donne/comments/commentRss/76327.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/donne/services/trackbacks/76327.html</trackback:ping><description><![CDATA[1. main.py:<br /><div style="background-color:#eeeeee;font-size:13px;BORDER:1px solid #CCCCCC;PADDING-RIGHT: 5px;PADDING-BOTTOM: 4px;PADDING-left: 4px;PADDING-TOP: 4px;WIDTH: 98%;word-break:break-all"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #008080; "> 1</span> <span style="color: #008000; ">#</span><span style="color: #008000; ">!/bin/env python</span><span style="color: #008000; "><br /></span><span style="color: #008080; "> 2</span> <span style="color: #008000; ">#</span><span style="color: #008000; ">-*-coding:utf-8-*-</span><span style="color: #008000; "><br /></span><span style="color: #008080; "> 3</span> <span style="color: #008000; "></span><span style="color: #000000; "><br /></span><span style="color: #008080; "> 4</span> <span style="color: #000000; "></span><span style="color: #0000FF; ">import</span><span style="color: #000000; "> sys<br /></span><span style="color: #008080; "> 5</span> <span style="color: #000000; "></span><span style="color: #0000FF; ">from</span><span style="color: #000000; "> twisted.python </span><span style="color: #0000FF; ">import</span><span style="color: #000000; "> log<br /></span><span style="color: #008080; "> 6</span> <span style="color: #000000; ">log.startLogging(sys.stdout)<br /></span><span style="color: #008080; "> 7</span> <span style="color: #000000; "><br /></span><span style="color: #008080; "> 8</span> <span style="color: #000000; "></span><span style="color: #0000FF; ">from</span><span style="color: #000000; "> twisted.internet </span><span style="color: #0000FF; ">import</span><span style="color: #000000; "> protocol, reactor<br /></span><span style="color: #008080; "> 9</span> <span style="color: #000000; "><br /></span><span style="color: #008080; ">10</span> <span style="color: #000000; "></span><span style="color: #0000FF; ">class</span><span style="color: #000000; "> SubProcessProtocol(protocol.ProcessProtocol):<br /></span><span style="color: #008080; ">11</span> <span style="color: #000000; ">    </span><span style="color: #0000FF; ">def</span><span style="color: #000000; "> </span><span style="color: #800080; ">__init__</span><span style="color: #000000; ">(self):<br /></span><span style="color: #008080; ">12</span> <span style="color: #000000; ">        self.input </span><span style="color: #000000; ">=</span><span style="color: #000000; "> </span><span style="color: #000000; ">97</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">13</span> <span style="color: #000000; "><br /></span><span style="color: #008080; ">14</span> <span style="color: #000000; ">    </span><span style="color: #0000FF; ">def</span><span style="color: #000000; "> connectionMade(self):<br /></span><span style="color: #008080; ">15</span> <span style="color: #000000; ">        log.msg(</span><span style="color: #800000; ">'</span><span style="color: #800000; ">Connection Made.</span><span style="color: #800000; ">'</span><span style="color: #000000; ">)<br /></span><span style="color: #008080; ">16</span> <span style="color: #000000; ">        self.send()<br /></span><span style="color: #008080; ">17</span> <span style="color: #000000; "><br /></span><span style="color: #008080; ">18</span> <span style="color: #000000; ">    </span><span style="color: #0000FF; ">def</span><span style="color: #000000; "> send(self):<br /></span><span style="color: #008080; ">19</span> <span style="color: #000000; ">        self.transport.write(chr(self.input) </span><span style="color: #000000; ">+</span><span style="color: #000000; "> </span><span style="color: #800000; ">"</span><span style="color: #800000; ">\n</span><span style="color: #800000; ">"</span><span style="color: #000000; ">)<br /></span><span style="color: #008080; ">20</span> <span style="color: #000000; ">        log.msg(</span><span style="color: #800000; ">'</span><span style="color: #800000; ">Sent:</span><span style="color: #800000; ">'</span><span style="color: #000000; ">, chr(self.input))<br /></span><span style="color: #008080; ">21</span> <span style="color: #000000; ">        self.input </span><span style="color: #000000; ">+=</span><span style="color: #000000; "> </span><span style="color: #000000; ">1</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">22</span> <span style="color: #000000; "><br /></span><span style="color: #008080; ">23</span> <span style="color: #000000; ">    </span><span style="color: #0000FF; ">def</span><span style="color: #000000; "> outReceived(self, data):<br /></span><span style="color: #008080; ">24</span> <span style="color: #000000; ">        log.msg(</span><span style="color: #800000; ">'</span><span style="color: #800000; ">Received:</span><span style="color: #800000; ">'</span><span style="color: #000000; ">, data)<br /></span><span style="color: #008080; ">25</span> <span style="color: #000000; ">        reactor.callLater(.</span><span style="color: #000000; ">1</span><span style="color: #000000; ">, self.send)<br /></span><span style="color: #008080; ">26</span> <span style="color: #000000; "><br /></span><span style="color: #008080; ">27</span> <span style="color: #000000; ">    </span><span style="color: #0000FF; ">def</span><span style="color: #000000; "> errReceived(self, data):<br /></span><span style="color: #008080; ">28</span> <span style="color: #000000; ">        log.msg(</span><span style="color: #800000; ">'</span><span style="color: #800000; ">Error:</span><span style="color: #800000; ">'</span><span style="color: #000000; ">, data)<br /></span><span style="color: #008080; ">29</span> <span style="color: #000000; "><br /></span><span style="color: #008080; ">30</span> <span style="color: #000000; ">    </span><span style="color: #0000FF; ">def</span><span style="color: #000000; "> inConnectionLost(self):<br /></span><span style="color: #008080; ">31</span> <span style="color: #000000; ">        log.msg(</span><span style="color: #800000; ">'</span><span style="color: #800000; ">Error: inConnectionLost</span><span style="color: #800000; ">'</span><span style="color: #000000; ">)<br /></span><span style="color: #008080; ">32</span> <span style="color: #000000; "><br /></span><span style="color: #008080; ">33</span> <span style="color: #000000; ">    </span><span style="color: #0000FF; ">def</span><span style="color: #000000; "> outConnectionLost(self):<br /></span><span style="color: #008080; ">34</span> <span style="color: #000000; ">        log.msg(</span><span style="color: #800000; ">'</span><span style="color: #800000; ">Error: inConnectionLost</span><span style="color: #800000; ">'</span><span style="color: #000000; ">)<br /></span><span style="color: #008080; ">35</span> <span style="color: #000000; "><br /></span><span style="color: #008080; ">36</span> <span style="color: #000000; ">    </span><span style="color: #0000FF; ">def</span><span style="color: #000000; "> errConnectionLost(self):<br /></span><span style="color: #008080; ">37</span> <span style="color: #000000; ">        log.msg(</span><span style="color: #800000; ">'</span><span style="color: #800000; ">Error: errConnectionLost</span><span style="color: #800000; ">'</span><span style="color: #000000; ">)<br /></span><span style="color: #008080; ">38</span> <span style="color: #000000; "><br /></span><span style="color: #008080; ">39</span> <span style="color: #000000; ">    </span><span style="color: #0000FF; ">def</span><span style="color: #000000; "> processExited(self, reason):<br /></span><span style="color: #008080; ">40</span> <span style="color: #000000; ">        log.msg(</span><span style="color: #800000; ">'</span><span style="color: #800000; ">Process exit status:</span><span style="color: #800000; ">'</span><span style="color: #000000; ">,reason.value.exitCode )<br /></span><span style="color: #008080; ">41</span> <span style="color: #000000; "><br /></span><span style="color: #008080; ">42</span> <span style="color: #000000; ">    </span><span style="color: #0000FF; ">def</span><span style="color: #000000; "> processEnded(self, reason):<br /></span><span style="color: #008080; ">43</span> <span style="color: #000000; ">        log.msg(</span><span style="color: #800000; ">'</span><span style="color: #800000; ">Process end status:</span><span style="color: #800000; ">'</span><span style="color: #000000; ">,reason.value.exitCode )<br /></span><span style="color: #008080; ">44</span> <span style="color: #000000; ">        </span><span style="color: #0000FF; ">if</span><span style="color: #000000; "> reactor.running:<br /></span><span style="color: #008080; ">45</span> <span style="color: #000000; ">            reactor.stop()<br /></span><span style="color: #008080; ">46</span> <span style="color: #000000; "><br /></span><span style="color: #008080; ">47</span> <span style="color: #000000; "></span><span style="color: #0000FF; ">def</span><span style="color: #000000; "> main():<br /></span><span style="color: #008080; ">48</span> <span style="color: #000000; ">    p </span><span style="color: #000000; ">=</span><span style="color: #000000; "> SubProcessProtocol()<br /></span><span style="color: #008080; ">49</span> <span style="color: #000000; ">    reactor.spawnProcess(p, </span><span style="color: #800000; ">'</span><span style="color: #800000; ">sub.py</span><span style="color: #800000; ">'</span><span style="color: #000000; ">, [</span><span style="color: #800000; ">'</span><span style="color: #800000; ">sub.py</span><span style="color: #800000; ">'</span><span style="color: #000000; ">], {})<br /></span><span style="color: #008080; ">50</span> <span style="color: #000000; ">    reactor.run()<br /></span><span style="color: #008080; ">51</span> <span style="color: #000000; "><br /></span><span style="color: #008080; ">52</span> <span style="color: #000000; "></span><span style="color: #0000FF; ">if</span><span style="color: #000000; "> </span><span style="color: #800080; ">__name__</span><span style="color: #000000; "> </span><span style="color: #000000; ">==</span><span style="color: #000000; "> </span><span style="color: #800000; ">"</span><span style="color: #800000; ">__main__</span><span style="color: #800000; ">"</span><span style="color: #000000; ">:<br /></span><span style="color: #008080; ">53</span> <span style="color: #000000; ">    main()</span></div><br />2. sub.py:<br /><div style="background-color:#eeeeee;font-size:13px;BORDER:1px solid #CCCCCC;PADDING-RIGHT: 5px;PADDING-BOTTOM: 4px;PADDING-left: 4px;PADDING-TOP: 4px;WIDTH: 98%;word-break:break-all"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #008080; "> 1</span> <span style="color: #008000; ">#</span><span style="color: #008000; ">!/bin/env python</span><span style="color: #008000; "><br /></span><span style="color: #008080; "> 2</span> <span style="color: #008000; ">#</span><span style="color: #008000; ">-*-coding:utf-8-*-</span><span style="color: #008000; "><br /></span><span style="color: #008080; "> 3</span> <span style="color: #008000; "></span><span style="color: #000000; "><br /></span><span style="color: #008080; "> 4</span> <span style="color: #000000; "></span><span style="color: #0000FF; ">import</span><span style="color: #000000; "> sys, os<br /></span><span style="color: #008080; "> 5</span> <span style="color: #000000; ">sys.stdout </span><span style="color: #000000; ">=</span><span style="color: #000000; "> os.fdopen(sys.stdout.fileno(), </span><span style="color: #800000; ">'</span><span style="color: #800000; ">w</span><span style="color: #800000; ">'</span><span style="color: #000000; ">, </span><span style="color: #000000; ">1</span><span style="color: #000000; ">)<br /></span><span style="color: #008080; "> 6</span> <span style="color: #000000; "><br /></span><span style="color: #008080; "> 7</span> <span style="color: #000000; "><br /></span><span style="color: #008080; "> 8</span> <span style="color: #000000; "></span><span style="color: #0000FF; ">def</span><span style="color: #000000; "> main():<br /></span><span style="color: #008080; "> 9</span> <span style="color: #000000; ">    running </span><span style="color: #000000; ">=</span><span style="color: #000000; "> True<br /></span><span style="color: #008080; ">10</span> <span style="color: #000000; "><br /></span><span style="color: #008080; ">11</span> <span style="color: #000000; ">    </span><span style="color: #0000FF; ">while</span><span style="color: #000000; "> running:<br /></span><span style="color: #008080; ">12</span> <span style="color: #000000; ">        input </span><span style="color: #000000; ">=</span><span style="color: #000000; "> sys.stdin.readline().rstrip(</span><span style="color: #800000; ">'</span><span style="color: #800000; ">\n</span><span style="color: #800000; ">'</span><span style="color: #000000; ">)<br /></span><span style="color: #008080; ">13</span> <span style="color: #000000; ">        </span><span style="color: #0000FF; ">if</span><span style="color: #000000; "> input </span><span style="color: #000000; ">==</span><span style="color: #000000; "> </span><span style="color: #800000; ">'</span><span style="color: #800000; ">q</span><span style="color: #800000; ">'</span><span style="color: #000000; ">:<br /></span><span style="color: #008080; ">14</span> <span style="color: #000000; ">            running </span><span style="color: #000000; ">=</span><span style="color: #000000; "> False<br /></span><span style="color: #008080; ">15</span> <span style="color: #000000; "><br /></span><span style="color: #008080; ">16</span> <span style="color: #000000; ">        </span><span style="color: #0000FF; ">print</span><span style="color: #000000; "> </span><span style="color: #800000; ">"</span><span style="color: #800000; ">You said:%s</span><span style="color: #800000; ">"</span><span style="color: #000000; "> </span><span style="color: #000000; ">%</span><span style="color: #000000; "> input<br /></span><span style="color: #008080; ">17</span> <span style="color: #000000; "><br /></span><span style="color: #008080; ">18</span> <span style="color: #000000; "></span><span style="color: #0000FF; ">if</span><span style="color: #000000; "> </span><span style="color: #800080; ">__name__</span><span style="color: #000000; "> </span><span style="color: #000000; ">==</span><span style="color: #000000; "> </span><span style="color: #800000; ">"</span><span style="color: #800000; ">__main__</span><span style="color: #800000; ">"</span><span style="color: #000000; ">:<br /></span><span style="color: #008080; ">19</span> <span style="color: #000000; ">    main()<br /></span><span style="color: #008080; ">20</span> <span style="color: #000000; ">    sys.exit(</span><span style="color: #000000; ">2</span><span style="color: #000000; ">)</span></div><br /><br /><br /><img src ="http://www.cnitblog.com/donne/aggbug/76327.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/donne/" target="_blank">Don Li</a> 2011-11-16 16:32 <a href="http://www.cnitblog.com/donne/archive/2011/11/16/76327.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>VS 2005中实现对Python 2.5.2的模块扩展实验</title><link>http://www.cnitblog.com/donne/archive/2008/12/04/52200.html</link><dc:creator>Don Li</dc:creator><author>Don Li</author><pubDate>Thu, 04 Dec 2008 08:13:00 GMT</pubDate><guid>http://www.cnitblog.com/donne/archive/2008/12/04/52200.html</guid><wfw:comment>http://www.cnitblog.com/donne/comments/52200.html</wfw:comment><comments>http://www.cnitblog.com/donne/archive/2008/12/04/52200.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/donne/comments/commentRss/52200.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/donne/services/trackbacks/52200.html</trackback:ping><description><![CDATA[以下为实验步骤：<br />一、VS 2005：<br />1. 新建Win32 Application, Application type: DLL, Additional options: Empty project.<br />2. Projects and Solutions-&gt;VC++ Directores中，新增&lt;Python&gt;\include目录到Include files和library files.<br />3. 新增Source Files:<br />hello.c:<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #000000">#include </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">Python.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" />#include </span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #0000ff">string</span><span style="COLOR: #000000">.h</span><span style="COLOR: #000000">&gt;</span><span style="COLOR: #000000"><br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img id="Codehighlighter1_98_300_Open_Image" onclick="this.style.display='none'; Codehighlighter1_98_300_Open_Text.style.display='none'; Codehighlighter1_98_300_Closed_Image.style.display='inline'; Codehighlighter1_98_300_Closed_Text.style.display='inline';" src="http://www.cnitblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_98_300_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_98_300_Closed_Text.style.display='none'; Codehighlighter1_98_300_Open_Image.style.display='inline'; Codehighlighter1_98_300_Open_Text.style.display='inline';" src="http://www.cnitblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> PyObject </span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">message(PyObject </span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">self, PyObject </span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">args) </span><span id="Codehighlighter1_98_300_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cnitblog.com/images/dot.gif" /></span><span id="Codehighlighter1_98_300_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000"> </span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">fromPython, result[</span><span style="COLOR: #000000">64</span><span style="COLOR: #000000">];<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    <br /><img src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000"> (</span><span style="COLOR: #000000">!</span><span style="COLOR: #000000">PyArg_Parse(args, </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">(s)</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">, </span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">fromPython))<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> NULL;<br /><img id="Codehighlighter1_199_298_Open_Image" onclick="this.style.display='none'; Codehighlighter1_199_298_Open_Text.style.display='none'; Codehighlighter1_199_298_Closed_Image.style.display='inline'; Codehighlighter1_199_298_Closed_Text.style.display='inline';" src="http://www.cnitblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_199_298_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_199_298_Closed_Text.style.display='none'; Codehighlighter1_199_298_Open_Image.style.display='inline'; Codehighlighter1_199_298_Open_Text.style.display='inline';" src="http://www.cnitblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />    </span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000"> </span><span id="Codehighlighter1_199_298_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cnitblog.com/images/dot.gif" /></span><span id="Codehighlighter1_199_298_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        strcpy(result, </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">Hello, </span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">);<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        strcat(result, fromPython);<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align="top" />        </span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"> Py_BuildValue(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">s</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">, result);<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/ExpandedSubBlockEnd.gif" align="top" />    }</span></span><span style="COLOR: #000000"><br /><img src="http://www.cnitblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="COLOR: #000000"><br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img id="Codehighlighter1_347_391_Open_Image" onclick="this.style.display='none'; Codehighlighter1_347_391_Open_Text.style.display='none'; Codehighlighter1_347_391_Closed_Image.style.display='inline'; Codehighlighter1_347_391_Closed_Text.style.display='inline';" src="http://www.cnitblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_347_391_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_347_391_Closed_Text.style.display='none'; Codehighlighter1_347_391_Open_Image.style.display='inline'; Codehighlighter1_347_391_Open_Text.style.display='inline';" src="http://www.cnitblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" /></span><span style="COLOR: #0000ff">static</span><span style="COLOR: #000000"> </span><span style="COLOR: #0000ff">struct</span><span style="COLOR: #000000"> PyMethodDef hello_methods[] </span><span style="COLOR: #000000">=</span><span style="COLOR: #000000"> </span><span id="Codehighlighter1_347_391_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cnitblog.com/images/dot.gif" /></span><span id="Codehighlighter1_347_391_Open_Text"><span style="COLOR: #000000">{<br /><img id="Codehighlighter1_351_373_Open_Image" onclick="this.style.display='none'; Codehighlighter1_351_373_Open_Text.style.display='none'; Codehighlighter1_351_373_Closed_Image.style.display='inline'; Codehighlighter1_351_373_Closed_Text.style.display='inline';" src="http://www.cnitblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_351_373_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_351_373_Closed_Text.style.display='none'; Codehighlighter1_351_373_Open_Image.style.display='inline'; Codehighlighter1_351_373_Open_Text.style.display='inline';" src="http://www.cnitblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />        </span><span id="Codehighlighter1_351_373_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cnitblog.com/images/dot.gif" /></span><span id="Codehighlighter1_351_373_Open_Text"><span style="COLOR: #000000">{</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">message</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">, message, </span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">}</span></span><span style="COLOR: #000000">,<br /><img id="Codehighlighter1_378_389_Open_Image" onclick="this.style.display='none'; Codehighlighter1_378_389_Open_Text.style.display='none'; Codehighlighter1_378_389_Closed_Image.style.display='inline'; Codehighlighter1_378_389_Closed_Text.style.display='inline';" src="http://www.cnitblog.com/images/OutliningIndicators/ExpandedSubBlockStart.gif" align="top" /><img id="Codehighlighter1_378_389_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_378_389_Closed_Text.style.display='none'; Codehighlighter1_378_389_Open_Image.style.display='inline'; Codehighlighter1_378_389_Open_Text.style.display='inline';" src="http://www.cnitblog.com/images/OutliningIndicators/ContractedSubBlock.gif" align="top" />        </span><span id="Codehighlighter1_378_389_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cnitblog.com/images/dot.gif" /></span><span id="Codehighlighter1_378_389_Open_Text"><span style="COLOR: #000000">{NULL, NULL}</span></span><span style="COLOR: #000000"><br /><img src="http://www.cnitblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="COLOR: #000000">;<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img id="Codehighlighter1_433_481_Open_Image" onclick="this.style.display='none'; Codehighlighter1_433_481_Open_Text.style.display='none'; Codehighlighter1_433_481_Closed_Image.style.display='inline'; Codehighlighter1_433_481_Closed_Text.style.display='inline';" src="http://www.cnitblog.com/images/OutliningIndicators/ExpandedBlockStart.gif" align="top" /><img id="Codehighlighter1_433_481_Closed_Image" style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_433_481_Closed_Text.style.display='none'; Codehighlighter1_433_481_Open_Image.style.display='inline'; Codehighlighter1_433_481_Open_Text.style.display='inline';" src="http://www.cnitblog.com/images/OutliningIndicators/ContractedBlock.gif" align="top" />_declspec(dllexport) </span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000"> inithello() </span><span id="Codehighlighter1_433_481_Closed_Text" style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cnitblog.com/images/dot.gif" /></span><span id="Codehighlighter1_433_481_Open_Text"><span style="COLOR: #000000">{<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/InBlock.gif" align="top" />    (</span><span style="COLOR: #0000ff">void</span><span style="COLOR: #000000">)Py_InitModule(</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">hello</span><span style="COLOR: #000000">"</span><span style="COLOR: #000000">, hello_methods);<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/ExpandedBlockEnd.gif" align="top" />}</span></span><span style="COLOR: #000000"><br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /></span></div><br />4. 以Release方式Build。<br />5. 修改扩展名.dll为pyd.<br /><br />二、Python：<br />1. copy刚才生成的hello.pyd到项目目录下，或者可以import的lib目录。<br />2. 新建main.py:<br /><div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000"> hello<br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /><br /><img src="http://www.cnitblog.com/images/OutliningIndicators/None.gif" align="top" /></span><span style="COLOR: #0000ff">print</span><span style="COLOR: #000000"> hello.message(</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">hhahhah</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">)</span></div><br />搞定。<br /><img src ="http://www.cnitblog.com/donne/aggbug/52200.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/donne/" target="_blank">Don Li</a> 2008-12-04 16:13 <a href="http://www.cnitblog.com/donne/archive/2008/12/04/52200.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Python项目的文档化开发</title><link>http://www.cnitblog.com/donne/archive/2008/09/26/49546.html</link><dc:creator>Don Li</dc:creator><author>Don Li</author><pubDate>Fri, 26 Sep 2008 03:19:00 GMT</pubDate><guid>http://www.cnitblog.com/donne/archive/2008/09/26/49546.html</guid><wfw:comment>http://www.cnitblog.com/donne/comments/49546.html</wfw:comment><comments>http://www.cnitblog.com/donne/archive/2008/09/26/49546.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/donne/comments/commentRss/49546.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/donne/services/trackbacks/49546.html</trackback:ping><description><![CDATA[<p style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">&nbsp;</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">在语言要求的地方注释，以标准的注释语法。<br>注释说明必要的信息，<br>适当的设计思路描述<br>适当的算法设计描述</p>
<p style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><br>文档化的工具： <br>&nbsp;&nbsp;&nbsp; 1. epydoc:<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 纯Python实现。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 与Python的结合非常自然，稳定，可扩展。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; 2. DoxyGen.<br>&nbsp;&nbsp;&nbsp; <br>epydoc标签规范：<br>&nbsp;&nbsp;&nbsp; 1. py文献信息：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @author:&nbsp;&nbsp; ...作者<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @license:&nbsp; ...版权<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @contact:&nbsp; ...联系<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; 2. py状态信息：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @version:&nbsp; ...版本推荐使用$Id$<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @todo[ver]:...改进，可以指定针对的版本<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; 3. py模块信息：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @var v: ...模块变量v说明<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @type v: ...模块变量类型v说明<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; 4. py函数信息：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @param p: ...参数p说明<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @type p: ...参数p类型说明<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @return: ...返回值说明<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @rtype: ...返回值类型说明<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; 5. py提醒信息：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @note: ...注解<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @attention: ...注意<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @bug: ... 问题<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @warning: ...警告<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; 6. py关联信息：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @see: ...参考资料<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>&nbsp;&nbsp;&nbsp; 7. py注释风格：</p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #008080">&nbsp;1</span><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #008000">#</span><span style="COLOR: #008000">xxxx.py文件模板</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">&nbsp;2</span><span style="COLOR: #008000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #800000">'''</span><span style="COLOR: #800000"><br></span><span style="COLOR: #008080">&nbsp;3</span><span style="COLOR: #800000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>@version:&nbsp;$Id$<br></span><span style="COLOR: #008080">&nbsp;4</span><span style="COLOR: #800000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>@author:&nbsp;U{username&lt;mailto:&nbsp;email_address&gt;}<br></span><span style="COLOR: #008080">&nbsp;5</span><span style="COLOR: #800000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>@see:&nbsp;资料<br></span><span style="COLOR: #008080">&nbsp;6</span><span style="COLOR: #800000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #800000">'''</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">&nbsp;7</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br></span><span style="COLOR: #008080">&nbsp;8</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000">&nbsp;sys,&nbsp;os,&nbsp;other<br></span><span style="COLOR: #008080">&nbsp;9</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br></span><span style="COLOR: #008080">10</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;Templates(object):<br></span><span style="COLOR: #008080">11</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #800000">'''</span><span style="COLOR: #800000"><br></span><span style="COLOR: #008080">12</span><span style="COLOR: #800000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;类说明<br></span><span style="COLOR: #008080">13</span><span style="COLOR: #800000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #800000">'''</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">14</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800080">__init__</span><span style="COLOR: #000000">(self,&nbsp;param1):<br></span><span style="COLOR: #008080">15</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #800000">'''</span><span style="COLOR: #800000"><br></span><span style="COLOR: #008080">16</span><span style="COLOR: #800000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@param&nbsp;param1:&nbsp;注释内容。<br></span><span style="COLOR: #008080">17</span><span style="COLOR: #800000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@type&nbsp;param1:&nbsp;介绍。<br></span><span style="COLOR: #008080">18</span><span style="COLOR: #800000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@return:&nbsp;返回简介。<br></span><span style="COLOR: #008080">19</span><span style="COLOR: #800000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;@rtype&nbsp;v：&nbsp;返回类型简介。<br></span><span style="COLOR: #008080">20</span><span style="COLOR: #800000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #800000">'''</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">21</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.param1&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;param1</span></div>
<br><span style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">&nbsp;&nbsp;&nbsp;&nbsp;8. 特殊标签：<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; U{text&lt;url&gt;}： URL<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; L{text&lt;object&gt;}：交叉引用，自动生成到其他对象的文档页面链接。<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; object为对象名称， 类/函数/变量名</span>
<img src ="http://www.cnitblog.com/donne/aggbug/49546.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/donne/" target="_blank">Don Li</a> 2008-09-26 11:19 <a href="http://www.cnitblog.com/donne/archive/2008/09/26/49546.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>最大公约数算法</title><link>http://www.cnitblog.com/donne/archive/2008/07/23/47050.html</link><dc:creator>Don Li</dc:creator><author>Don Li</author><pubDate>Wed, 23 Jul 2008 08:29:00 GMT</pubDate><guid>http://www.cnitblog.com/donne/archive/2008/07/23/47050.html</guid><wfw:comment>http://www.cnitblog.com/donne/comments/47050.html</wfw:comment><comments>http://www.cnitblog.com/donne/archive/2008/07/23/47050.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/donne/comments/commentRss/47050.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/donne/services/trackbacks/47050.html</trackback:ping><description><![CDATA[1. 欧几里德算法和扩展欧几里德算法<br>1). 欧几里德算法<br>欧几里德算法又称辗转相除法， 用于计算两个整数a, b的最大公约数。其计算原理依赖于下面的定理：<br>定理： gcd(a, b) = gcd(b, a mod b)<br><br>证明：<br>&nbsp; a可以表示成a = kb + r, 则r = a mod b<br>&nbsp; 假设d是a, b的一个公约数， 则有&nbsp; d|a, d|b, 而r = a - kb, 因此d|r。<br>&nbsp; 因此，d是(b, a mod b)的公约数。<br>&nbsp; 加上d是(b，a mod b)的公约数，则d|b, d|r, 但是a = kb + r,因此d也是(a, b)的公约数。<br>&nbsp; 因此，(a, b) 和(a, a mod b)的公约数是一样的，其最大公约数也必然相等，得证。<br><br>欧几里德的Python语言描述为：<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;gcd(a,&nbsp;b):<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;a&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">&nbsp;b:<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;a,&nbsp;b&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;b,&nbsp;a<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;</span><span style="COLOR: #0000ff">while</span><span style="COLOR: #000000">&nbsp;b&nbsp;</span><span style="COLOR: #000000">!=</span><span style="COLOR: #000000">&nbsp;0:<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;temp&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;a&nbsp;</span><span style="COLOR: #000000">%</span><span style="COLOR: #000000">&nbsp;b<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;a&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;b<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;b&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;temp<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;a</span></div>
<br>2. Stein算法<br>欧几里德算法是计算两个数最大公约数的传统算法，无论是理论，还是从效率上都是很好的。但是他有一个致命的缺陷，这个缺陷只有在很大的素数时才会显现出来。<br>考虑现在的硬件平台，一般整数最多也就是64位， 对于这样的整数，计算两个数值就的模很简单的。对于字长为32位的平台，计算两个不超过32位的整数的模，只需要一个指令周期，而计算64位以下的整数模，也不过几个周期而已。但是对于更大的素数，这样的计算过程就不得不由用户来设计，为了计算两个超过64位的整数的模，用户也许不得不采用类似于多位除法手算过程中的试商法，这个过程不但复杂，而且消耗了很多CPU时间。对于现代密码算法，要求计算128位以上的素数的情况比比皆是，设计这样的程序迫切希望能够抛弃除法和取模。<br>Stein算法由J.Stein 1961年提出，这个方法也是计算两个数的最大公约数。和欧几里德算法不同的是，Stein算法只有整数的移位和加减法，这对于程序设计者是一个福音。<br>为了说明Stein算法的正确性，首先必须注意到以下结论：<br>&nbsp; gcd(a, a) = a， 也就是一个数和他自己的公约数是其自身。<br>&nbsp; gcd(ka, kb) = k * gcd(a, b)，也就是最大公约数运算和倍乘运算可以交换，特殊的，当k=2时，说明两个偶数的最大公约数比如能被2整除。<br>Stein算法的python实现如下：<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;gcd_Stein(a,&nbsp;b):&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;a&nbsp;</span><span style="COLOR: #000000">&lt;</span><span style="COLOR: #000000">&nbsp;b:<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a,&nbsp;b&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;b,&nbsp;a<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;(0&nbsp;</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">&nbsp;b):<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;a<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;a&nbsp;</span><span style="COLOR: #000000">%</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">&nbsp;0&nbsp;</span><span style="COLOR: #0000ff">and</span><span style="COLOR: #000000">&nbsp;b&nbsp;</span><span style="COLOR: #000000">%</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">&nbsp;0:<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;gcd_Stein(a</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,&nbsp;b</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">)<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;a&nbsp;</span><span style="COLOR: #000000">%</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">&nbsp;0:<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;gcd_Stein(a&nbsp;</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,&nbsp;b)<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;b&nbsp;</span><span style="COLOR: #000000">%</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">&nbsp;0:<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;gcd_Stein(a,&nbsp;b&nbsp;</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">)<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;gcd_Stein((a&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;b)&nbsp;</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">,&nbsp;(a&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">&nbsp;b)&nbsp;</span><span style="COLOR: #000000">/</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">)&nbsp;</span></div>
<br><br><br>
<img src ="http://www.cnitblog.com/donne/aggbug/47050.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/donne/" target="_blank">Don Li</a> 2008-07-23 16:29 <a href="http://www.cnitblog.com/donne/archive/2008/07/23/47050.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用来做搜索日志负载测试的一段脚本</title><link>http://www.cnitblog.com/donne/archive/2008/05/16/43811.html</link><dc:creator>Don Li</dc:creator><author>Don Li</author><pubDate>Fri, 16 May 2008 08:47:00 GMT</pubDate><guid>http://www.cnitblog.com/donne/archive/2008/05/16/43811.html</guid><wfw:comment>http://www.cnitblog.com/donne/comments/43811.html</wfw:comment><comments>http://www.cnitblog.com/donne/archive/2008/05/16/43811.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnitblog.com/donne/comments/commentRss/43811.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/donne/services/trackbacks/43811.html</trackback:ping><description><![CDATA[共三个文件：<br><br>1. settings.py:<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #008000">#</span><span style="COLOR: #008000">-*-&nbsp;coding:&nbsp;utf-8&nbsp;-*-</span><span style="COLOR: #008000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>SETTINGS&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;{<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">SITE</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">:&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">http://xx.xxxx.com</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">,<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">USERS_COUNT</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">:&nbsp;</span><span style="COLOR: #000000">10</span><span style="COLOR: #000000">,<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">TIMES_PER_USER</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">:&nbsp;</span><span style="COLOR: #000000">1000</span><span style="COLOR: #000000">,<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">channels</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">:[</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">ring</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">wml</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">video</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">image</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">game</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">theme</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">,</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">sms</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">soft</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">read</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">,],<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</span></div>
<br><br>2.VUser.py:<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #008000">#</span><span style="COLOR: #008000">-*-&nbsp;coding:&nbsp;utf-8&nbsp;-*-</span><span style="COLOR: #008000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000">&nbsp;urllib2,&nbsp;logging,&nbsp;re<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #800080">__author__</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000"><a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#100;&#111;&#110;&#110;&#101;&#46;&#99;&#110;&#64;&#103;&#109;&#97;&#105;&#108;&#46;&#99;&#111;&#109;">donne.cn@gmail.com</a></span><span style="COLOR: #800000">"</span><span style="COLOR: #000000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #800080">__version__</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">0.1.0</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #800080">__copyright__</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">Copyright&nbsp;(c)&nbsp;2008&nbsp;donne.cn</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #800080">__license__</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">donne.cn</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #800080">__doc__</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800000">'''</span><span style="COLOR: #800000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;模拟用户访问目标站点，可以模拟主页访问，搜索，详情，下载一连串行为<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #800000">'''</span><span style="COLOR: #000000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>logging.basicConfig(level</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">logging.DEBUG,<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;format</span><span style="COLOR: #000000">=</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">%(asctime)s&nbsp;%(levelname)s&nbsp;%(message)s</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">,<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">#</span><span style="COLOR: #008000">filename='./FluxStatLoadTest.log',</span><span style="COLOR: #008000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;filemode</span><span style="COLOR: #000000">=</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">w</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">)<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;VUser(object):<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800080">__init__</span><span style="COLOR: #000000">(self,&nbsp;url,&nbsp;channel&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;None):<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self._channels&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;{<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">ring</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">:&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">Sring.wml</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">,&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">wml</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">:&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">Search.wml</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">,&nbsp;&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">video</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">:&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">Svideo.wml</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">,<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">image</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">:&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">Simage.wml</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">game</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">:&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">Sgame.wml</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">,&nbsp;&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">theme</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">:&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">Stheme.wml</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">,<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">sms</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">:&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">Sms.wml</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">soft</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">:&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">Ssoft.wml</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">,&nbsp;&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">read</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">:&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">Sread.wml</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">,<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self._url&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;url<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self._channel&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">Sring.wml</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;channel:<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self._channel&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;self._channels[channel]<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.id&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800000">''</span><span style="COLOR: #000000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;getDetailUrl(self,&nbsp;content):<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_url&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;re.compile(</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">&lt;br/&gt;&lt;a&nbsp;href="(.*?)"&gt;1.</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">).\<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;search(content,&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">).group(</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">).split(</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">)[</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;self.urlFormat(_url)<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;getDownloadUrl(self,&nbsp;content):<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;self._channel&nbsp;</span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000">&nbsp;[</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">Search.wml</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">Sms.wml</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">Sread.wml</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">,]:<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800000">''</span><span style="COLOR: #000000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_url&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;re.compile(</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">/&gt;&lt;a&nbsp;href="(.*?)"&gt;&#x514D;&#x8D39;&#x4E0B;&#x8F7D;</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">).\<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;search(content).group(</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;self.urlFormat(self._url&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">/</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;_url)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;getSearchUrl(self):&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.id&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;self._getSessionId(self.getPage(self._url))<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;self.urlFormat(self._url&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">/</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;self._channel&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">;jsessionid=</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;self.id&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">?q=mm</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">)<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;_getSessionId(self,&nbsp;content):<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;re.compile(</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">;jsessionid=(.*?)"&gt;&lt;</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">).\<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;search(content).group(</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">)<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;urlFormat(self,&nbsp;url):<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;str(url).replace(</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">&amp;amp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">&amp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">).replace(</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">./</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">,&nbsp;self._url&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">/</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">)<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;getPage(self,&nbsp;url):<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;url:<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;req&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;urllib2.Request(url)<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;req.add_header(</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">User-Agent</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">Roboo-QA-FluxLoadTester&nbsp;0.1.0&nbsp;by&nbsp;Don.Li</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">)<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;urllib2.urlopen(req).read()<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;search(self,&nbsp;url):<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;self.getDetailUrl(self.getPage(url))<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800080">__name__</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">__main__</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;user&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;VUser('</span><span style="COLOR: #800000"></span><span style="COLOR: #800000"><a href="http://xxx.xxxx.com'/">http://xxx.xxxx.com'</a></span><span style="COLOR: #800000"></span><span style="COLOR: #000000">,&nbsp;channel</span><span style="COLOR: #000000">=</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">theme</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">)<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;logging.info(user.id)<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;url&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;user.getSearchUrl()<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;url&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;user.getDetailUrl(user.getPage(url))<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;logging.info(</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">Detail&nbsp;URL:&nbsp;</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;url)<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;url&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;user.getDownloadUrl(user.getPage(url))<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;logging.info(</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">Download&nbsp;URL:&nbsp;</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;url)<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;user.getPage(url)</span></div>
<br>3. scenices.py:<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #008000">#</span><span style="COLOR: #008000">-*-&nbsp;coding:&nbsp;utf-8&nbsp;-*-</span><span style="COLOR: #008000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000">&nbsp;logging,&nbsp;threading<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">from</span><span style="COLOR: #000000">&nbsp;time&nbsp;</span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000">&nbsp;sleep<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">from</span><span style="COLOR: #000000">&nbsp;VUser&nbsp;</span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000">&nbsp;VUser<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">from</span><span style="COLOR: #000000">&nbsp;settings&nbsp;</span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000">&nbsp;SETTINGS<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #800080">__author__</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800000">"donne.cn@gmail.com</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #800080">__version__</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">0.1.0</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #800080">__copyright__</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">Copyright&nbsp;(c)&nbsp;2008&nbsp;donne.cn</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #800080">__license__</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">donne.cn</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #800080">__doc__</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800000">'''</span><span style="COLOR: #800000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;根据参数控制虚拟用户的行为<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #800000">'''</span><span style="COLOR: #000000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>logging.basicConfig(level</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">logging.DEBUG,<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;format</span><span style="COLOR: #000000">=</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">%(asctime)s&nbsp;%(levelname)s&nbsp;%(message)s</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">,<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">#</span><span style="COLOR: #008000">filename='./FluxStatLoadTest.log',</span><span style="COLOR: #008000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;filemode</span><span style="COLOR: #000000">=</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">w</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">)<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;threadUser(threading.Thread):<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800080">__init__</span><span style="COLOR: #000000">(self,&nbsp;name,&nbsp;channel&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;None):&nbsp;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self._name&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;name&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self._user&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;VUser(SETTINGS[</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">SITE</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">],&nbsp;channel)<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.vp&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;0<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;threading.Thread.</span><span style="COLOR: #800080">__init__</span><span style="COLOR: #000000">(self,&nbsp;name&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;name)<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;run(self):<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;i&nbsp;</span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000">&nbsp;range(SETTINGS[</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">TIMES_PER_USER</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">]):<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_url&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;self._user.getSearchUrl()<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_url&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;self._user.getDetailUrl(self._user.getPage(_url))<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logging.info(</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">Detail&nbsp;URL:&nbsp;</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;_url)<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sleep(</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">)<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_url&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;self._user.getDownloadUrl(self._user.getPage(_url))<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logging.info(</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">Download&nbsp;URL:&nbsp;</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;_url)<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sleep(</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">)<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self._user.getPage(_url)<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.vp&nbsp;</span><span style="COLOR: #000000">+=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">4</span><span style="COLOR: #000000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;logging.info(</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">The&nbsp;User&nbsp;</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;self._name&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">&nbsp;VP&nbsp;is:&nbsp;</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;str(self.vp)&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">&nbsp;Now.</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">)<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800080">__name__</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">__main__</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">:<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;users&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;[]<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;i&nbsp;</span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000">&nbsp;range(</span><span style="COLOR: #000000">9</span><span style="COLOR: #000000">):<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;channel&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;SETTINGS[</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">channels</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">][i]<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;j&nbsp;</span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000">&nbsp;range(SETTINGS[</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">USERS_COUNT</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">]):<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;user&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;threadUser(channel&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">&nbsp;Thread&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;str(j&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">),&nbsp;channel&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;channel)<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;users.append(user)<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;user&nbsp;</span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000">&nbsp;users:<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;user.start()<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;user&nbsp;</span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000">&nbsp;users:<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;user.join()</span></div>
<br><br>修改settings.py里的参数，运行scenices.py, 可以实现指定类型的指定数目的虚拟用户，并发访问目标网站，生成可以预估的log文件，对网站log生成功能实现负载测试，以期发现其中缺陷。
<img src ="http://www.cnitblog.com/donne/aggbug/43811.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/donne/" target="_blank">Don Li</a> 2008-05-16 16:47 <a href="http://www.cnitblog.com/donne/archive/2008/05/16/43811.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一段用来合并多个大型文本文件的脚本</title><link>http://www.cnitblog.com/donne/archive/2008/05/13/43675.html</link><dc:creator>Don Li</dc:creator><author>Don Li</author><pubDate>Tue, 13 May 2008 09:22:00 GMT</pubDate><guid>http://www.cnitblog.com/donne/archive/2008/05/13/43675.html</guid><wfw:comment>http://www.cnitblog.com/donne/comments/43675.html</wfw:comment><comments>http://www.cnitblog.com/donne/archive/2008/05/13/43675.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/donne/comments/commentRss/43675.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/donne/services/trackbacks/43675.html</trackback:ping><description><![CDATA[<p>为了合并几个好几十兆的文本文件到一个，使用复制，粘贴时，发现一次复制不完。所以，就写了这个东东：<br></p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000">&nbsp;os<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;FileIntegrater(object):<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800080">__init__</span><span style="COLOR: #000000">(self,&nbsp;fn):<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self._fhandle&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;open(fn,&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">a+</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">)<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.length&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;len(self._fhandle.readlines())<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;append(self,&nbsp;fn):<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_contents&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;[]<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;os.path.isfile(fn):<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_contents&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;open(fn,&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">rb</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">).readlines()<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_len&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;len(_contents)<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self._fhandle.writelines(_contents)<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self._fhandle.flush()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.length&nbsp;</span><span style="COLOR: #000000">+=</span><span style="COLOR: #000000">&nbsp;_len<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">print</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">INFO:</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">,&nbsp;fn,&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">[length:&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;repr(_len)&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">]</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">has&nbsp;been&nbsp;appended.</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000">:<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">print</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">ERROR:</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">,&nbsp;fn,&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">is&nbsp;not&nbsp;a&nbsp;file.</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;close(self):<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self._fhandle.close()<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800080">__name__</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">__main__</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">:<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;fi&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;FileIntegrater(</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">e:/log/cn1res1.roboo.com_editsystem_20080511_1.log</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">)<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;fi.append(</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">e:/log/editsystem.log.3</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">)<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;fi.append(</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">e:/log/editsystem.log.2</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">)<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;fi.append(</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">e:/log/editsystem.log.1</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">)<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;fi.append(</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">e:/log/editsystem.log</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">)<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">print</span><span style="COLOR: #000000">&nbsp;fi.length<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;fi.close()<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;os.remove(</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">e:/log/cn1res1.roboo.com_editsystem_20080511_1.log</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">)&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></div>
<img src ="http://www.cnitblog.com/donne/aggbug/43675.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/donne/" target="_blank">Don Li</a> 2008-05-13 17:22 <a href="http://www.cnitblog.com/donne/archive/2008/05/13/43675.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Uppacking Argument Lists</title><link>http://www.cnitblog.com/donne/archive/2008/03/26/41508.html</link><dc:creator>Don Li</dc:creator><author>Don Li</author><pubDate>Wed, 26 Mar 2008 08:06:00 GMT</pubDate><guid>http://www.cnitblog.com/donne/archive/2008/03/26/41508.html</guid><wfw:comment>http://www.cnitblog.com/donne/comments/41508.html</wfw:comment><comments>http://www.cnitblog.com/donne/archive/2008/03/26/41508.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/donne/comments/commentRss/41508.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/donne/services/trackbacks/41508.html</trackback:ping><description><![CDATA[The reverse situation occurs when the arguments are already in a list or tuple but need to be unpacked for a function call requiring separate positional argrumets.&nbsp;For instance, the built-in range() function expects separate start and stop arguments. If they are not available separately, write the function call with the * operator to unpack the arguments out of a list or tuple:<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">args&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;[</span><span style="COLOR: #000000">3</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">8</span><span style="COLOR: #000000">]<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">print</span><span style="COLOR: #000000">&nbsp;range(</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">args)&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">#</span><span style="COLOR: #008000">call&nbsp;with&nbsp;arguments&nbsp;unpacked&nbsp;from&nbsp;a&nbsp;list</span></div>
<br>In the same fashion, dictionaries can deliver keyword arguments with the ** operator:<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;parrot(voltage,&nbsp;state</span><span style="COLOR: #000000">=</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">a&nbsp;stiff</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">,&nbsp;action</span><span style="COLOR: #000000">=</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">voom</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">):<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;</span><span style="COLOR: #0000ff">print</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">--&nbsp;This&nbsp;parrot&nbsp;wouldn't</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">,&nbsp;action,<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;</span><span style="COLOR: #0000ff">print</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">if&nbsp;you&nbsp;put</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">,&nbsp;voltage,&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">volts&nbsp;through&nbsp;it.</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">,<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;</span><span style="COLOR: #0000ff">print</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">E's</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">,&nbsp;state,&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">!</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>d&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;{</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">voltage</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">:&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">four&nbsp;million</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">state</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">:&nbsp;</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">bleedin'&nbsp;demised</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">action</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">:&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">VOOM</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">}<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>parrot(</span><span style="COLOR: #000000">**</span><span style="COLOR: #000000">d)</span></div>
<br>
<img src ="http://www.cnitblog.com/donne/aggbug/41508.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/donne/" target="_blank">Don Li</a> 2008-03-26 16:06 <a href="http://www.cnitblog.com/donne/archive/2008/03/26/41508.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>decorator的使用</title><link>http://www.cnitblog.com/donne/archive/2008/03/25/41441.html</link><dc:creator>Don Li</dc:creator><author>Don Li</author><pubDate>Tue, 25 Mar 2008 06:49:00 GMT</pubDate><guid>http://www.cnitblog.com/donne/archive/2008/03/25/41441.html</guid><wfw:comment>http://www.cnitblog.com/donne/comments/41441.html</wfw:comment><comments>http://www.cnitblog.com/donne/archive/2008/03/25/41441.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/donne/comments/commentRss/41441.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/donne/services/trackbacks/41441.html</trackback:ping><description><![CDATA[<p>使用在Python 2.4 or Later.<br><br>两种调用形式：<br>1.不带参数</p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">@A<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;f():</span></div>
<p>Python最后会处理为：</p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">f&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;A(f)</span></div>
<p>，可扩展为：</p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">@A<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>@B<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>@C<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;f():<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><img src="http://www.cnitblog.com/Images/dot.gif"></span></div>
<p>最终Python会处理为:<br></p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">f&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;A(B(C(f)))</span></div>
<p>&nbsp;</p>
<p>2.带参数：<br></p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">@A(args)<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;f():<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><img src="http://www.cnitblog.com/Images/dot.gif"></span></div>
<p>Python会处理为：<br></p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;f();<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;_deco&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;A(args)<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;f&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;_deco(f)</span></div>
<p>Python先执行A(args)得到_deco，然后跟第一种方式一样的处理函数f。<br><br><br>对应的两种函数定义方法：<br>第一种：<br></p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;A(func):<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;</span><span style="COLOR: #008000">#</span><span style="COLOR: #008000">处理func</span><span style="COLOR: #008000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;</span><span style="COLOR: #008000">#</span><span style="COLOR: #008000">如func.attr='decorated'</span><span style="COLOR: #008000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;func<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>@A<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;f(args):&nbsp;</span><span style="COLOR: #0000ff">pass</span></div>
<p>A对f处理完后，仍返回函数对象。 如果要返回一个新的函数，可以为：<br></p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;A(func):<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;</span><span style="COLOR: #008000">#</span><span style="COLOR: #008000">做额外的工作</span><span style="COLOR: #008000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;</span><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;new_func(args):<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">#</span><span style="COLOR: #008000">做额外工作</span><span style="COLOR: #008000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;func(args)&nbsp;&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;new_func<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>@A<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;f(args):&nbsp;</span><span style="COLOR: #0000ff">pass</span></div>
<p>注意：new_func的定义形式要和待处理的函数相同。<br><br>如果想根据原来函数的结果进行一些处理：<br></p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;A(func):<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;</span><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;new_func(</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">args,&nbsp;</span><span style="COLOR: #000000">**</span><span style="COLOR: #000000">argkw):<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;result&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;func(</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">args,&nbsp;</span><span style="COLOR: #000000">**</span><span style="COLOR: #000000">argkw)<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;result:<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;new_result<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000">:<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;result<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;new_func<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>@A<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;f(args):&nbsp;</span><span style="COLOR: #0000ff">pass</span><span style="COLOR: #000000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span></div>
<p><br>&nbsp;</p>
<p>第二种：&nbsp;</p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;A(arg):<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;</span><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;_A(func):<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;new_func(args):<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">#</span><span style="COLOR: #008000">do&nbsp;any&nbsp;operation</span><span style="COLOR: #008000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;func(args)<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;new_func<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;_A<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>@A(arg)<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;f(args):&nbsp;</span><span style="COLOR: #0000ff">pass</span></div>
<p>文档上说：如果你的decorator在调用时使用了参数，那么你的decorator函数只会使用这些参数进行调用。因此你需要返回一个新的decorator函数，就和第一种方式定义形式一致了。</p>
<p><br><br>&nbsp;</p>
<img src ="http://www.cnitblog.com/donne/aggbug/41441.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/donne/" target="_blank">Don Li</a> 2008-03-25 14:49 <a href="http://www.cnitblog.com/donne/archive/2008/03/25/41441.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[Twisted]Deferred Object</title><link>http://www.cnitblog.com/donne/archive/2008/03/24/41381.html</link><dc:creator>Don Li</dc:creator><author>Don Li</author><pubDate>Mon, 24 Mar 2008 00:59:00 GMT</pubDate><guid>http://www.cnitblog.com/donne/archive/2008/03/24/41381.html</guid><wfw:comment>http://www.cnitblog.com/donne/comments/41381.html</wfw:comment><comments>http://www.cnitblog.com/donne/archive/2008/03/24/41381.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/donne/comments/commentRss/41381.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/donne/services/trackbacks/41381.html</trackback:ping><description><![CDATA[<p>Twisted uses the Deferred object to manage the callback sequence. The client application attaches a series of functions to the deferred to be called in order when the results of the asychronous request are available(this series of functions is known as a series of callbacks, or a callback chain), together with a series of functions to be called if there is an error in the asychronous request(known as a series of errbacks or an errback chain). The asychronous library code calls the first callback when the result is available, or the first errback when an error occurs, and the Deferred object then hands the results of each callback or errback function to the next function in the chain.<br>&nbsp; <br>The Problem that Deferreds Solve<br>It is the second class of concurrency problem - non-computationally intensive tasks that involve an appreciable delay - that Deferreds are designed to help solve. Functions that wait on hard drive access, database access, and network access all fall into this class, although the time delay varies.<br>Deferreds are designed to enable Twisted programs to wait for data without hanging until that data arrives. They do this by giving a simple management interface for callbacks to libraries and applications.&nbsp; Libraries know that they always make their results available by calling Deferred.callback and error by calling Deferred.errback. Applications set up result handlers by attaching callbacks and errbacks to deferreds in the order they want them called.<br><br>The basic idea behind Deferreds, and other solutions to this problem, is to keep the CPU as active as possible. If one task is waiting on data, rather than have the CPU(and the program!) idle waiting for that data(a process normally called "blocking"), the program performs other operations in the meantime, and waits for some singnal that data is ready to be processed before returning to that process.<br>In Twisted, a function signals to the calling function that it is waiting by returning a Deferred. When the data is available, the program activeates the callbacks on that Deferred to process the data.</p>
<p>Deferreds - a signal that data is yet to come<br>In our email sending example above, a parent functions calls a function to connect to the remote server. Asynchrony requires that this connection function return without waiting for the result so that the parent function can do other things. So how does the parent function or its controlling program know that the connection doesn't exist yet, and how does it use the connection once it does exist?<br>Twisted has an object that signals this situation. When the connection function returns, it signals that the operation is imcomplete by returning a twisted.internet.defer.Deferred object.<br>The Deferred has two purposes. The first is that it says "I am a signal that the result of whatever you wanted me to do is still pending.". The second is that you can ask the Deferred to run things when the data does arrive.</p>
<p>Callbacks<br>The way you tell a Deferred what to do with the data once it arrives is by adding a callback - asking the Deferred to call a function once the data arrives.<br>One Twisted library function that returns a Deferred is twisted.web.client.getPage. In this example, we call getPage, which returns a Deferred, and we attach a callback to handle the contents of the page once the data is available:</p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">from</span><span style="COLOR: #000000">&nbsp;twisted.web.client&nbsp;</span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000">&nbsp;getPage<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">from</span><span style="COLOR: #000000">&nbsp;twisted.internet&nbsp;</span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000">&nbsp;reactor<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;printContents(contents):<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp; </span><span style="COLOR: #800000">'''</span><span style="COLOR: #800000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp; This&nbsp;is&nbsp;the&nbsp;'callback'&nbsp;function,&nbsp;added&nbsp;to&nbsp;the&nbsp;Deferred&nbsp;and&nbsp;called&nbsp;by&nbsp;it&nbsp;when&nbsp;the&nbsp;promised&nbsp;data&nbsp;is&nbsp;available<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;</span><span style="COLOR: #800000">'''</span><span style="COLOR: #000000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;</span><span style="COLOR: #0000ff">print</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800000">"</span><span style="COLOR: #800000">The&nbsp;Deferred&nbsp;has&nbsp;called&nbsp;printContents&nbsp;with&nbsp;the&nbsp;following&nbsp;contents:</span><span style="COLOR: #800000">"</span><span style="COLOR: #000000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;</span><span style="COLOR: #0000ff">print</span><span style="COLOR: #000000">&nbsp;contents<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;</span><span style="COLOR: #008000">#</span><span style="COLOR: #008000">Stop&nbsp;the&nbsp;Twisted&nbsp;event&nbsp;handling&nbsp;system&nbsp;--&nbsp;this&nbsp;is&nbsp;usually&nbsp;handled</span><span style="COLOR: #008000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #008000">#</span><span style="COLOR: #008000">in&nbsp;higher&nbsp;lever&nbsp;ways</span><span style="COLOR: #008000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">&nbsp;reactor.stop()<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #008000">#</span><span style="COLOR: #008000">call&nbsp;getPage,&nbsp;which&nbsp;returns&nbsp;immediately&nbsp;with&nbsp;a&nbsp;Deferred,&nbsp;promissing&nbsp;to</span><span style="COLOR: #008000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>#</span><span style="COLOR: #008000">pass&nbsp;the&nbsp;page&nbsp;contents&nbsp;onto&nbsp;our&nbsp;callbacks&nbsp;when&nbsp;the&nbsp;contents&nbsp;are&nbsp;available</span><span style="COLOR: #008000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">deferred&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;getPage(</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">http://www.google.com</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">)<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #008000">#</span><span style="COLOR: #008000">added&nbsp;a&nbsp;callback&nbsp;to&nbsp;the&nbsp;deferred&nbsp;--&nbsp;request&nbsp;that&nbsp;it&nbsp;run&nbsp;printContents&nbsp;when</span><span style="COLOR: #008000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>#</span><span style="COLOR: #008000">the&nbsp;page&nbsp;content&nbsp;has&nbsp;been&nbsp;downloaded</span><span style="COLOR: #008000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">deferred.addCallback(printContents)<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #008000">#</span><span style="COLOR: #008000">Begin&nbsp;the&nbsp;Twisted&nbsp;event&nbsp;handling&nbsp;system&nbsp;to&nbsp;manage&nbsp;the&nbsp;process&nbsp;--&nbsp;again</span><span style="COLOR: #008000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>#</span><span style="COLOR: #008000">&nbsp;this&nbsp;isn't&nbsp;the&nbsp;usual&nbsp;way&nbsp;to&nbsp;do&nbsp;this</span><span style="COLOR: #008000"><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">reactor.run()<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span></div>
<p>&#160;</p>
<p>A very common use of Deferreds is to attach two callbacks. The result of the first callback is passed to the second callback:</p>
<p>from twisted.web.client import getPage<br>from twisted.internet import reactor</p>
<p>def lowerCaseContents(contents):<br>&nbsp;'''<br>&nbsp;This is a 'callback' function, added to the Deferred and called by<br>&nbsp;it when the promised data is available. It converts all the data to lower case.<br>&nbsp;'''<br>&nbsp;return contents.lower()<br>&nbsp;<br>def printContents(contents):<br>&nbsp;'''<br>&nbsp;This a 'callback' function, added to the Deferred after lowerCaseContents<br>&nbsp;and called by it with the results of lowerCaseContents<br>&nbsp;'''<br>&nbsp;print contents<br>&nbsp;reactor.stop()<br>&nbsp;<br>deferred = getPage('http://www.google.com')</p>
<p>#add two callbacks to the deferred -- request that it run lowerCaseContents<br>#when the page content has been downloaded, and then run printContents with<br>#the result of lowerCaseContents<br>deferred.addCallback(lowerCaseContents)<br>deferred.addCallback(printContents)</p>
<p>reactor.run()</p>
<p>Error handling: errbacks<br>Just as a asynchronous function returns before its result is available, it may also return before it is possible to detect errors: failed connections, erroneous data, protocol errors, and so on. Just as you can add callbacks to a Deferred which it calls when the data you are expecting is available, you can add error handlers(errbacks) to a Deferred for it to call when an error occurs and it cannot obtain the data:</p>
<p>from twisted.web.client import getPage<br>from twisted.internet import reactor</p>
<p>def errorHandler(err):<br>&nbsp;'''<br>&nbsp;This is an 'errback' function, added to the Deferred which will call it in the event of an error<br>&nbsp;'''<br>&nbsp;<br>&nbsp;#this isn't a very effective handling of the error, we just print it out:<br>&nbsp;print "An error has occurred: &lt;%s&gt;" % str(err)<br>&nbsp;#and then we stop the entire process:<br>&nbsp;reactor.stop()<br>&nbsp;<br>def printContents(contents):<br>&nbsp;'''<br>&nbsp;This is a 'callback' function, added to the Deferred and called by it which the page content<br>&nbsp;'''<br>&nbsp;print contents<br>&nbsp;reactor.stop()<br>&nbsp;<br>#we request a page which doesn't exist in order to demonstrate the<br>#error chain<br>deferred = getPage("<a href="http://www.google.com/does-not-exits">http://www.google.com/does-not-exits</a>")</p>
<p>#add the callback to the Deferred to handle the page content<br>deferred.addCallback(printContents)</p>
<p>#add the errback to the Deferred to handle any errors<br>deferred.addErrback(errorHandler)</p>
<p>reactor.run()</p>
<img src ="http://www.cnitblog.com/donne/aggbug/41381.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/donne/" target="_blank">Don Li</a> 2008-03-24 08:59 <a href="http://www.cnitblog.com/donne/archive/2008/03/24/41381.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Python基础笔记摘要</title><link>http://www.cnitblog.com/donne/archive/2008/03/24/41380.html</link><dc:creator>Don Li</dc:creator><author>Don Li</author><pubDate>Mon, 24 Mar 2008 00:57:00 GMT</pubDate><guid>http://www.cnitblog.com/donne/archive/2008/03/24/41380.html</guid><wfw:comment>http://www.cnitblog.com/donne/comments/41380.html</wfw:comment><comments>http://www.cnitblog.com/donne/archive/2008/03/24/41380.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cnitblog.com/donne/comments/commentRss/41380.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/donne/services/trackbacks/41380.html</trackback:ping><description><![CDATA[<p>1. Python牛。</p>
<p>3. 一切皆为对象，对象都有名字。</p>
<p>4. 基本数据类型和c/c++相像，但是1 == 1.0, 原因：float和int比较时，会把int转为long, 再把long转为double，float也被转为double。</p>
<p>5. None是特殊变量。跟C中的NULL不完全一样。</p>
<p>6. bool型，很多的情况都可以作为false，如0， 0.0，[], {}, None等。感觉不错，这个世界就应该把是和非直接平衡些。</p>
<p>7. IndentationError: expected an indented block: 缩进问题。</p>
<p>9. list列表，叫什么都无所谓，数组， Vector都行。</p>
<p>10.list一个特别的地方，可以使用负数索引。</p>
<p>11.list常用操作：<br>&nbsp; list的截取： a[3:5], a[3:], a[:]<br>&nbsp; list的追加： a.append(var)<br>&nbsp; 某个元素在list出现的次数: a.count(var)<br>&nbsp; list长度： len(list)<br>&nbsp; list追加一个list： a.extend(list)<br>&nbsp; 返回某元素在list中的位置： a.index(var)<br>&nbsp; list中插入： a.insert(index, var)<br>&nbsp; list弹出最后或指定位置的元素： a.pop(), a.pop(index)<br>&nbsp; list找到某值，删除之： a.remove(var)<br>&nbsp; list中倒次序： a.reverse()<br>&nbsp; list排序： a.sort()， a.sort(func),使用func(x, y)作为规则排序<br>&nbsp; <br>12.很好玩的一个东西： <br>&nbsp; [&lt;expr1&gt; for k in L if &lt;expr2&gt;]<br>&nbsp; 例子： [k + 1 for k in a if type(k) == types.IntType]<br>&nbsp; <br>16. 序列sequence<br>&nbsp;&nbsp;sequence就是list，string，tuple的总称。<br>&nbsp;&nbsp;它们之间的共性就是以下操作：<br>&nbsp;&nbsp; (a). in判断某个object是否在sequence中。<br>&nbsp;&nbsp; (b). len取得sequence的长度<br>&nbsp;&nbsp; (c). 可以使用下标操作：sequence[i]<br>&nbsp;&nbsp; (d). 取子sequence用sequence[start:end],<br>&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;取得的子sequence下标为[start, start+1,...,end-1],不是到end结束。<br>&nbsp;&nbsp; (e). 用+号可以连接sequence.<br>&nbsp;&nbsp; (f). 用乘号*可以重复几个sequence.<br>&nbsp;&nbsp; (g). 可以使用list comprehension: [&lt;expr1&gt; for k in L if &lt;expr2&gt;]<br>&nbsp;&nbsp; <br>22. 函数参数的设置<br>&nbsp;&nbsp;(a). 默认参数<br>&nbsp;&nbsp;(b). 参数个数可变： **对应dictionary，*对应tuple。<br>&nbsp;&nbsp;&nbsp;&nbsp; 例如：def printf(format, *args), 调用方式: printf("%d,%d", 1, 3)<br>&nbsp;&nbsp;&nbsp;&nbsp; 而：<br>&nbsp;&nbsp;&nbsp;&nbsp; def printf(format, **args),调用方式：printf("ok", One=1, Two=2, Three=3)<br>&nbsp;&nbsp;&nbsp;&nbsp; 注意： **和*参数必须为最后一个参数。<br>&nbsp;&nbsp;&nbsp;&nbsp; <br>25. 函数的作用域： LGB准则就是Python找变量的次序： Local - Global - Build-in</p>
<p>26. 函数可以嵌套，但内部的函数不能访问外部的变量。</p>
<p>&nbsp;</p>
<img src ="http://www.cnitblog.com/donne/aggbug/41380.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/donne/" target="_blank">Don Li</a> 2008-03-24 08:57 <a href="http://www.cnitblog.com/donne/archive/2008/03/24/41380.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[Twisted]Asynchronous Programming with Twisted</title><link>http://www.cnitblog.com/donne/archive/2008/03/20/41251.html</link><dc:creator>Don Li</dc:creator><author>Don Li</author><pubDate>Thu, 20 Mar 2008 08:07:00 GMT</pubDate><guid>http://www.cnitblog.com/donne/archive/2008/03/20/41251.html</guid><wfw:comment>http://www.cnitblog.com/donne/comments/41251.html</wfw:comment><comments>http://www.cnitblog.com/donne/archive/2008/03/20/41251.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/donne/comments/commentRss/41251.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/donne/services/trackbacks/41251.html</trackback:ping><description><![CDATA[&nbsp; This document is a instroduction to the asynchronous programming model, and to Twisted's Deferred abstraction, which symbolises a 'promised' result and which can pass an eventual result to handler functions.<br>&nbsp; This document is for readers new to Twisted who are familiar with the Python programming language and, at least conceptually, with core networking conepts such as servers, clients and sockets. This document will give you a high level overview of concurrent programming(interleaving several tasks) and of Twisted's concurrency model:<br>non-blocking code or asynchronous code.<br>&nbsp; After discussing the concurrency model of which deferreds are a part, it will introduce the methods of handing results when a function returns a Deferred object.<br><br><br><br>Many computing tasks take some time to complete, and there are two reasons why a task might take some time:<br>1. it is computationally intensive(for example factorising large numbers) and requires a certain amount of CPU time to calculate the answer;<br>2. it is not computationally intensive but has to wait for data to be available to produce a result.<br><br><br>Waiting for answers<br>&nbsp; A fundamental feature of network programming is that of waiting for data. Imagine you have a function which sends an email summarising some information. This function needs to connect to a remote server, wait for the remote server to reply, check that the remote server can process the email, wait for the reply, send the mail ,wait for the confirmation, and then disconnect.<br>&nbsp; Any one of these steps may take a long period of time. Your program might use the simplest of all possible models, in which it actually sits and waits for data to be sent and received, but in this case it has some very obvious and basic limitations: it can't send many emails at once; and in fact it can't do anything else while it is sending an email.<br>&nbsp; Hence, all but the simplest network programs avoid this model. You can use one of several different models to allow your program to keep doing whatever tasks it has on hand while it is waiting for something to happen before a particular task can continue.<br><br><br>Not waiting on data<br>&nbsp; There are many ways to write network programs. The main ones are:<br>&nbsp; 1. handle each connection in a separate operating system process, in which case the operating system will take care of letting other processes run while one is waiting.<br>&nbsp; 2. handle each connection in a separate thread in which the threading framework takes care of letting other threads run while one is waiting for.<br>&nbsp; 3. use non-blocking system calls to handle all connections in one thread.<br><br><br>Non-blocking calls<br>&nbsp; The normal model when using the Twisted framework is the third model: non-blocking calls.<br>&nbsp; When dealing with many connections in one thread the scheduling is the responsibility of the application.not the operating system. and is usually implemented by calling a registered function when each connection is ready to for reading or writing - commonly known as asynchronous, event-driven or callback-based programming.<br><br>&nbsp; In this model, the earlier email sending function would work something like this:<br>&nbsp;&nbsp;&nbsp; 1. it calls a connection function to connect the remote server;<br>&nbsp;&nbsp;&nbsp; 2. the connection function returns immediately, with the implication that the notify the email sending library will be called when the connect has been made.<br>&nbsp;&nbsp;&nbsp; 3. once the connection is made, the connect mechanism notifies the email sending function that the connection is ready. <br>&nbsp; What advantage does the above sequence have over our original blocking sequence?The advantage is that while the email sending function can't do the next part of its job until the connection is open, the rest of the program can do other tasks, like begin the opening sequence for other email connections. Hence, the entire program is not waiting for the connection.<br><br>Callbacks<br>&nbsp; The typical asynchronous model for alerting an application that some data is ready for it is known as a callback. The application calls a function to request some data, and in this call, it also passes a callback function that should be called when the data is ready with the data as an argument. The callback function should therefore perform whatever tasks it was that the application needed that data for.<br>&nbsp; In synchonous programming, a function requests data, waits for the data, and then processes it. In asynchronous programming, a function requests the data, and lets the library call the callback function when the data is ready.
<img src ="http://www.cnitblog.com/donne/aggbug/41251.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/donne/" target="_blank">Don Li</a> 2008-03-20 16:07 <a href="http://www.cnitblog.com/donne/archive/2008/03/20/41251.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[Twisted]Using Processes</title><link>http://www.cnitblog.com/donne/archive/2008/03/17/41032.html</link><dc:creator>Don Li</dc:creator><author>Don Li</author><pubDate>Mon, 17 Mar 2008 05:23:00 GMT</pubDate><guid>http://www.cnitblog.com/donne/archive/2008/03/17/41032.html</guid><wfw:comment>http://www.cnitblog.com/donne/comments/41032.html</wfw:comment><comments>http://www.cnitblog.com/donne/archive/2008/03/17/41032.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/donne/comments/commentRss/41032.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/donne/services/trackbacks/41032.html</trackback:ping><description><![CDATA[Along with connection to servers across the internet, Twisted also connects to local processes with much the same API. The API is described in more detail in the documentation of :<br>&nbsp; twisted.internet.interfaces.IReactorProcess<br>&nbsp; twisted.internet.interfaces.IProcessTransport<br>&nbsp; twisted.internet.protocol.ProcessProtocol<br><br>Processes are run through the reactor, using reactor.spawnProcess().Pipes are created to the child process, and added to the reactor core so that the application will not block while sending data into or pulling data out of the new process. reactor.spawnProcess() requires two arguments, processProtocol and executable, and optionally takes six more: arguments, environment, path, userID, groupID, and usePTY.<br><br>&nbsp; from twisted.internet import reactor<br>&nbsp; reactor.spawnProcess(processProtocol, executable, args=[program, arg1, arg2], env={'HOME': os.environ['HOME']}, path, uid, gid, usePTY, childFDs)<br><br>processProtocol should be an instance of a subclass of twisted.internet.protocol.ProcessProtocol. The interface is described below:<br>&nbsp; executable is the full path of the program to run. It will be connected to processProtocol.<br>&nbsp; args is a list of command line arguments to be passed to the process. args[0] should be the name of the process.<br>&nbsp; env is a dictionary containing the environment to pass through to the process.<br>&nbsp; path is the directory to run the process in. The child will switch to the given directory just before starting the new program. The default is to stay in the current directory.<br>&nbsp; uid and gid are the user ID and group ID to run the subprcess as. Of course, changing identities will be more likely to succeed if you start as root.<br>&nbsp; usePTY specifies whether the child process should be run with a pty, or if it should just get a pair of pipes. Interactive programs(where you don't know when it may read or write) need to be run with ptys.<br>&nbsp; childFDs lets you specify how the child's file descriptors should be set up. Each key is a file descriptor number(an integer) as seen by the child. 0, 1 and 2 are usually stdin, stdout, and stderr, but some programes may be instructed to use addtional fds through command-line arguments or environment variables. Each value is either an interger specifying one of the parent's current file descriptors, the string 'r' which creates a pipe that the parent can read from, or the string 'w' which creates a pipe that the parent can write to. If childFDs is not provided, a default is used which creates the usual stdin-writer, stdout-reader, and stderr-reader pipes.<br><br>args and env have empty default values. but many programes depend upon them to be set correctly. At the very leaset, args[0] should probably be the same as wxecutable. If you just provide os.environ.for env, the child program will inherit the environment from the current process. which is usually the civilized thing to do(unless you want to explicitly clean the environment as a security precaution). The default is to give an empty env to the child. <br>reactor.spawnProcess() returns an instance that implements the twisted.internet.interfaces.IProcessTransport.<br>
<img src ="http://www.cnitblog.com/donne/aggbug/41032.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/donne/" target="_blank">Don Li</a> 2008-03-17 13:23 <a href="http://www.cnitblog.com/donne/archive/2008/03/17/41032.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[Twisted]Reactor Overview</title><link>http://www.cnitblog.com/donne/archive/2008/03/16/40988.html</link><dc:creator>Don Li</dc:creator><author>Don Li</author><pubDate>Sun, 16 Mar 2008 01:13:00 GMT</pubDate><guid>http://www.cnitblog.com/donne/archive/2008/03/16/40988.html</guid><wfw:comment>http://www.cnitblog.com/donne/comments/40988.html</wfw:comment><comments>http://www.cnitblog.com/donne/archive/2008/03/16/40988.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/donne/comments/commentRss/40988.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/donne/services/trackbacks/40988.html</trackback:ping><description><![CDATA[<p>1. Basics<br>&nbsp; The reactor is the core of the event loop with Twisted - the loop which drives applications using Twisted. The reactor provides basic interfaces to a number of services, including network communications, threading, and event dispatching. </p>
There are multiple implementations of the reactor, each modified to provide better support for specialized features over the default implementation. <br><br>Twisted applications can use the interfaces in twisted.application.service to configure and run the application instead of using boilerplate reactor code. <br><br>2. Using the reactor object<br>&nbsp; You can get to the reactor object using the following code:<br>&nbsp;&nbsp;&nbsp; from twisted.internet import reactor<br><br>&nbsp; The reactor usually implements a set of interfaces, but depending on the chosen reactor and the platform, some of the interfaces may not be implemented:<br>&nbsp; IReactorCore: Core(required) functionality.<br>&nbsp; IReactorFDSet: Use FileDescriptor objects.<br>&nbsp; IReactorProcess: Process management. <br>&nbsp; IReactorSSL: SSL networking support.<br>&nbsp; IReactorTCP: TCP networking support. <br>&nbsp; IReactorThreads: Threading use and management.<br>&nbsp; IReactorTime: Scheduling interface.<br>&nbsp; IReactorUDP: UDP networking support.<br>&nbsp; IReactorUNIX: UNIX socket support.
<img src ="http://www.cnitblog.com/donne/aggbug/40988.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/donne/" target="_blank">Don Li</a> 2008-03-16 09:13 <a href="http://www.cnitblog.com/donne/archive/2008/03/16/40988.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>从源码在同台linux服务器上安装2个MySQL心得</title><link>http://www.cnitblog.com/donne/archive/2008/02/28/40241.html</link><dc:creator>Don Li</dc:creator><author>Don Li</author><pubDate>Thu, 28 Feb 2008 05:18:00 GMT</pubDate><guid>http://www.cnitblog.com/donne/archive/2008/02/28/40241.html</guid><wfw:comment>http://www.cnitblog.com/donne/comments/40241.html</wfw:comment><comments>http://www.cnitblog.com/donne/archive/2008/02/28/40241.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnitblog.com/donne/comments/commentRss/40241.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/donne/services/trackbacks/40241.html</trackback:ping><description><![CDATA[1. 下载MYSQL源码包至/home/mysql_home。<br>&nbsp;&nbsp;&nbsp; 我下载下来的源码包文件名为:mysql-5.0.45.tar.gz<br><br>2. 在/home/mysql_home下，解压。<br>&nbsp;&nbsp;&nbsp; tar zxvf mysql-5.0.45.tar.gz<br><br>3. 进入/home/mysql_home/mysql-5.0.45/,执行：<br>&nbsp;./configure --with-tcp-port=33007 --with-unix-socket=/home/mysql_home/mysql.sock --prefix=/home/mysql_home/mysql --with-charset=utf8 --with-extra-charsets=all<br>make<br>make install<br><br>configure命令是修改默认的服务器端口和安装目录，数据库编码等参数。<br><br><br>然后安装无错后，<br><br>4. 确保系统已经有了mysql用户组和用户，然后赋/home/mysql_home所有权限给mysql.<br>chown -R mysql /home/mysql_home<br><br>5. 到mysql的安装目录=/home/mysql_home/mysql 下，执行：<br>./bin/mysqld_safe --log-error=./mysql.log --port=33007<br><br>6. 成功，一个新的MySQL服务启动在TCP 33007端口。<br><br>7. 登陆数据库，修改远程登陆的root权限：<br>mysql -P 33007<br>在mysql的环境下：<br>&nbsp;grant all on *.* to <a href='&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#114;&#111;&#111;&#116;&#64;&#34;&#37;'>root@"%</a>" Identified by "111111";<br><br>成功修改mysql账户root的密码为111111，可远程登录了。且与服务器上原有的MySQL服务不冲突。<br><br>
<img src ="http://www.cnitblog.com/donne/aggbug/40241.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/donne/" target="_blank">Don Li</a> 2008-02-28 13:18 <a href="http://www.cnitblog.com/donne/archive/2008/02/28/40241.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>unittest - TestLoader object</title><link>http://www.cnitblog.com/donne/archive/2008/02/02/39564.html</link><dc:creator>Don Li</dc:creator><author>Don Li</author><pubDate>Sat, 02 Feb 2008 09:03:00 GMT</pubDate><guid>http://www.cnitblog.com/donne/archive/2008/02/02/39564.html</guid><wfw:comment>http://www.cnitblog.com/donne/comments/39564.html</wfw:comment><comments>http://www.cnitblog.com/donne/archive/2008/02/02/39564.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/donne/comments/commentRss/39564.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/donne/services/trackbacks/39564.html</trackback:ping><description><![CDATA[the TestLoader class is used to create test suites for classes and modules. Normally, there is no need to create an instance of this class; the unittest module provides an instance that can be stared as unittest. defaultTestLoader. Using a subclass or instance, however, allows customization of some configurable properties.<br><br>TesLoader objects have the following methods:<br><br>loadTestsfromTestCase(testCaseClass)<br>&nbsp; Return a suite of all tests cases contained in the TestCase-derived testCaseClass.<br><br>loadTestsFromModule(module)<br>&nbsp; Return a suite of all tests cases contained in the given module. This method searches module for classes derived from TestCase and creates an instance of the class for each test method defined for the class.<br>&nbsp; Warning: While using a hierarchy of TestCase-derived classes can be converient in sharing fixtures and helper functions, defining test methods on base classes that are not intended to be instantiated directly does not play well with this method. Doing so, however, can be useful when the fixtures are different and defined in subclasses.<br><br>loadTestsFromName(name[, module])<br>&nbsp; Return a suite of all tests cases given a string specifier.<br>&nbsp; The specifier name is a 'dotted name' that may resolve either to a module, a test case class, a test method within a test case class, a TestSuite instance, or a callable object which returns a TestCase or TestSuite instance. These checks are applied in the order listed here; that is, a method on a possible test case class will be picked up as 'a test method within a test case class', rather than 'a callable object'.<br>&nbsp; For example, if you have a module SampleTests containing a TestCase-derived class SampleTestCase with thress testmethods(test_one(), test_two(), test_three()), the specifier 'SampleTests.SampleTestCase' would cause this method to return a suite which will run all thress test methods. Using the specifier 'SampleTests.SampleTestCase.test_two' would cause it to return a test suite which will run only the test_two() test method. The specifier can refer to modules and packages which have not been imported; they will be imported as a side-effect.<br>&nbsp; The method optionally resolves name relative to the given module.<br><br>loadTestsFromNames(names[, module])<br>&nbsp; Similar to loadTestsFromName(), but takes a sequence of names rather than a single name. The return value is a test suite which supports all the tests defined for each name.<br><br>getTestCaseNames(testCaseClass)<br>&nbsp; Return a sorted sequence of method names found within testCaseClass; this should be a subclass of TestCase.<br><br>The following attributes of a TestLoader can be configured either by subclassing or assignment on an instance:<br><br>testMethodPrefix<br>&nbsp; String giving the prefix of method names which will be interpreted as test methods. The default value is 'test'.<br>&nbsp; This affects getTestCaseNames() and all the loadTestsFrom*() methods.<br><br>sortTestMethodsUsing<br>&nbsp; Function to be used to compare method names when sorting them in getTestCaseNames() and all the loadTestsFrom*() methods. The default value is the built-in cmp() function. the attribute can also be set to None to disable the sort.<br><br>suiteClass<br>&nbsp; Callable object that constructs a test suite from a list of tests. No methods on the resulting object are needed. The default value is the TestSuite class.<br><br><br>This affects all the loadTestsFrom*() methods.
<img src ="http://www.cnitblog.com/donne/aggbug/39564.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/donne/" target="_blank">Don Li</a> 2008-02-02 17:03 <a href="http://www.cnitblog.com/donne/archive/2008/02/02/39564.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>unittest - TestCase Ojbects</title><link>http://www.cnitblog.com/donne/archive/2008/02/01/39540.html</link><dc:creator>Don Li</dc:creator><author>Don Li</author><pubDate>Fri, 01 Feb 2008 08:14:00 GMT</pubDate><guid>http://www.cnitblog.com/donne/archive/2008/02/01/39540.html</guid><wfw:comment>http://www.cnitblog.com/donne/comments/39540.html</wfw:comment><comments>http://www.cnitblog.com/donne/archive/2008/02/01/39540.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/donne/comments/commentRss/39540.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/donne/services/trackbacks/39540.html</trackback:ping><description><![CDATA[Each TestCase instance reprsents a single test, but each concrete subclass may be used to define multiple tests -- the concrete class represents a single test fixture. The fixture is created and cleaned up for each test case.<br><br>TestCase instances provide three groups of methods: one group used to run the test, another used by the test implementation to check conditions and report failures, and some inquiry methods allowing information about the test itself to be gathered.<br><br>Methods in the first group (running the test) are:<br>setUp()<br>&nbsp; Method called to prepare the test fixture. This is called immediately before calling the test method; any exception raised by this method will be considered an error rather than a test failure. The default implementation does nothing.<br><br>tearDown（）<br>&nbsp; Method called immediately after the test method has been called and the result recorded. This is called even if the test method raised an exception. so the implementation in subclass may need to be particularly carefuul about checking internal state. Any exception raised by this method will be considered an error rather than a test failure. This method will only be called if the setUp() succeeds, regardless of the outcome of the test method. The default implementation does nothing.<br><br>run([result])<br>&nbsp; Run the test, collecting the result into the test result object passed as result. If result is omitted or None, a temporary result object is created(by calling the defaultTestCase() method) and used; this result object is not returned to run()'s caller.<br>&nbsp; The same effect may be had by simply calling the TestCase instance.<br><br>debug()<br>&nbsp; Run the test without collecting the result. This allows exceptions raised by the test to be propagated to the caller, and can be used to support running tests under a debugger.<br>&nbsp; This test code can use any of the following methods to check for and report failures.<br><br>assert_(expr[, msg])<br>failUnless(expr[,msg])<br>&nbsp; Signal a test failure if expr is false; the explanation for the error will be msg if given, otherwise it will be None.<br><br>assertEqual(first, second[, msg])<br>failUnlessEqual(first, second[, msg])<br>&nbsp; Test that first and second are equal. If the values do not compare equal, the test will fail with the explanation given by msn, or None. Note that using failUnlessEqual() improves upon doing the comparison as the first parameter to failUnless(): the default value for msg can be computed to include representations of both first and second.<br><br>assertNotEqual(first, second[, msg])<br>failIfEqual(first, second[, msg])<br>&nbsp; Test that first and second are not equal. If the values do compare equal, the test will fail with the explaination given by msg, or None. Note that using failIfEqual() improves upon doing the comparison as the first parameter to failUnless() is that the default value for msg can be computed to include representations of both first and second.<br><br>assertAlmostEqual(first, second,[, places[, msg]])<br>failUnlessAlmostEqual(first, second, [, places[, msg]])<br>&nbsp; Test that first and second are approximately equal by computing the difference, rounding to thg given number of places, and comparing to zero. Note that comparing a given number of decimal places is not the same as comparing a given number of significant digits. If the values do not compare equal, the test will fail with the explantation given by msg, or None.<br><br>assertNotAlmostEqual(first, second,[, places[, msg]])<br>failIfAlmostEqual(first, second, [, places[, msg]])<br>&nbsp; Test that first and second are not&nbsp;approximately equal by computing the difference, rounding to thg given number of places, and comparing to zero. Note that comparing a given number of decimal places is not the same as comparing a given number of significant digits. If the values do not compare equal, the test will fail with the explantation given by msg, or None.<br><br>assertRaises(exception, callable, ...)<br>failUnlessRaises(exception, callable, ...)<br>&nbsp; Test that an exception is raised when callable is called with any positional or keyword arguments that are also passed to assertRaises(). The test passes if exception is raised, is an error if another exception raised, or fails if no exception is raised. To catch any of a group of exceptions, a tuple containing the exception classes may be passed as exception.<br><br>failIf(expr[, msg])<br>&nbsp; The inverse of the failUnless() method is the failIf() method. This signals a test failure if expr is true, with msg or None for the error message.<br><br>fail([msg])<br>&nbsp; Signals a test fialure unconditionally, with msg or None for the error message.<br><br>failureException<br>&nbsp; This class attribute gives the exception raised by the test() method. If a test framework needs to use a specialized exception, possibly to carry additional information, it must subclass this exception in order to 'play fair' with the framework. The initial value of this attribute is AssertionError.<br><br><br>Testing framework can use the following methods to collect information on the test:<br>countTestCases()<br>&nbsp; Return the number of tests represented by this test object. For TestCase instances, this will always be 1.<br><br>defaultTestResult()<br>&nbsp; Return an instance of the test result class that shoule be used for this test case class(if no other result instance is provided to the run() method);<br>&nbsp; For TestCase instances, this will always be an instance of TestResult, subclasses of TestCase should override this as necessary.<br><br>id()<br>&nbsp; Return a string identifying the specific test case. This is ususlly the full name of the test method, including the module and class name. <br><br>shortDescription()<br>&nbsp; Returns a one-line description of the test, or None if no description has been provided. The default implementation of this method returns the first line of the test method's docstring, if available, or None.
<img src ="http://www.cnitblog.com/donne/aggbug/39540.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/donne/" target="_blank">Don Li</a> 2008-02-01 16:14 <a href="http://www.cnitblog.com/donne/archive/2008/02/01/39540.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>unittest-Organizing test code</title><link>http://www.cnitblog.com/donne/archive/2008/01/31/39498.html</link><dc:creator>Don Li</dc:creator><author>Don Li</author><pubDate>Thu, 31 Jan 2008 03:03:00 GMT</pubDate><guid>http://www.cnitblog.com/donne/archive/2008/01/31/39498.html</guid><wfw:comment>http://www.cnitblog.com/donne/comments/39498.html</wfw:comment><comments>http://www.cnitblog.com/donne/archive/2008/01/31/39498.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/donne/comments/commentRss/39498.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/donne/services/trackbacks/39498.html</trackback:ping><description><![CDATA[The basic building blocks of unit testing are test cases -- single scenarios that must be set up and checked for correctness. In unittest, test cases are represented by instances of unittest's TestCase class. To make your own test cases you must write subclassed of TestCase, or use FunctionTestCase.<br><br>An instance of a TestCase-derived class in an object that can completely run a single test method, together with optional set-up and tidy-up code.<br><br>The testing code of a TestCase instance should be entirely self contained, such that it can be run either in isolation or in arbitrary combination with any number of other test cases.<br><br>The simplest TestCase subclass will simply override the runTest() method in order to perform specific testing code:
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #008080">1</span><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000">&nbsp;unittest<br></span><span style="COLOR: #008080">2</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br></span><span style="COLOR: #008080">3</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;DefaultWidgetSizeTestCase(unittest.TestCase):<br></span><span style="COLOR: #008080">4</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;</span><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;runTest(self):<br></span><span style="COLOR: #008080">5</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;widget&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;Widget(</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">The&nbsp;widget</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">)<br></span><span style="COLOR: #008080">6</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;self.assertEqual(widget.size(),&nbsp;(</span><span style="COLOR: #000000">50</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">50</span><span style="COLOR: #000000">),&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">incorrect&nbsp;default&nbsp;size</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">)</span></div>
<br>Note that in order to test something, we use the one of the assert*() or fail*() methods provided by the TestCase base class. If the test fails, an exception will be raised, and unittest will identify the test case as a failure. Any other exceptions will be treated as errors. This helps you identify where the problem is: failures are caused by incorrent results - a 5 where you expected a 6. Errors are caused by incorrect code - e.g., a TypeError caused by an incorrect function call.<br><br>The way to run a test case will be described later. For now, note that to construct an instance of such a test case, we call its constructor without arguments:<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">testcase&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;DefaultWidgetSizeTestCase()</span></div>
<p>Now, such test cases can be numerous, and their set-up can be repetitive. In the above case, constructin a Widget in each of 100 Widget test case subclass would mean unsightly duplication.</p>
<p>luckily, we can factor out such set-up code by implementing a method called setU(), which the testing framework will automatically call for us when we run the test:</p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #008080">&nbsp;1</span><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000">&nbsp;unittest<br></span><span style="COLOR: #008080">&nbsp;2</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br></span><span style="COLOR: #008080">&nbsp;3</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;SimpleWidgetTestCase(unittest.TestCase):<br></span><span style="COLOR: #008080">&nbsp;4</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;</span><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;setUp(self):<br></span><span style="COLOR: #008080">&nbsp;5</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;self.widget&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;Widget(</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">The&nbsp;widget</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">)<br></span><span style="COLOR: #008080">&nbsp;6</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br></span><span style="COLOR: #008080">&nbsp;7</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;DefaultWidgetSizeTestCase(SimpleWidgetTestCase):<br></span><span style="COLOR: #008080">&nbsp;8</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;</span><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;runTest(self):<br></span><span style="COLOR: #008080">&nbsp;9</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;self.failUnless(self.widget.size()&nbsp;</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #000000">50</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">50</span><span style="COLOR: #000000">),&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">incorrect&nbsp;default&nbsp;size</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">)<br></span><span style="COLOR: #008080">10</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br></span><span style="COLOR: #008080">11</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;WidgetResizeTestCase(SimpleWidgetTestCase):<br></span><span style="COLOR: #008080">12</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;</span><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;runTest(self):<br></span><span style="COLOR: #008080">13</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;self.widget.resize(</span><span style="COLOR: #000000">100</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">150</span><span style="COLOR: #000000">)<br></span><span style="COLOR: #008080">14</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;self.failUnless(self.widget.size()&nbsp;</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #000000">100</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">150</span><span style="COLOR: #000000">),&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">wrong&nbsp;size&nbsp;after&nbsp;resize</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">)</span></div>
<p>If the setUp() method raises an exception while the test is running, the framework will consider that test to have suffered an error, and the runTest() method will not be executed.<br><br>Similarly, we can provide a tearDown() method that tidies up after the runTest() method has been run:</p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #008080">1</span><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000">&nbsp;unittest<br></span><span style="COLOR: #008080">2</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br></span><span style="COLOR: #008080">3</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;SimpleWidgetTestCase(unittest.TestCase):<br></span><span style="COLOR: #008080">4</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;</span><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;setUp(self):<br></span><span style="COLOR: #008080">5</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;self.widget&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;Widget(</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">The&nbsp;widget</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">)<br></span><span style="COLOR: #008080">6</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br></span><span style="COLOR: #008080">7</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;</span><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;tearDown(self):<br></span><span style="COLOR: #008080">8</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;self.widget.dispose()<br></span><span style="COLOR: #008080">9</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;self.widget&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;None</span></div>
<p>If setUp() succeeded, the tearDown() method will be run whether runTest() succeeded or not.<br><br>Such a working environment for the testing code is called a fixture.<br><br>Often, many small test cases will use the same fixture. In this case, we would end up subclassing SimpleWidgetTestCase into many small one-method classed such as DefaultWidgetSizeTestCase. This is time-consuming and discouraging,&nbsp; so in the same vein as JUnit, unittest provides a simpler mechanism:<br></p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #008080">&nbsp;1</span><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000">&nbsp;unittest<br></span><span style="COLOR: #008080">&nbsp;2</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br></span><span style="COLOR: #008080">&nbsp;3</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;WidgetTestCase(unittest.TestCase):<br></span><span style="COLOR: #008080">&nbsp;4</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;</span><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;setUp(self):<br></span><span style="COLOR: #008080">&nbsp;5</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;self.widget&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;Widget(</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">The&nbsp;widget</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">)<br></span><span style="COLOR: #008080">&nbsp;6</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br></span><span style="COLOR: #008080">&nbsp;7</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;</span><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;tearDown(self):<br></span><span style="COLOR: #008080">&nbsp;8</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;self.widget.dispose()<br></span><span style="COLOR: #008080">&nbsp;9</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;self.widget&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;None<br></span><span style="COLOR: #008080">10</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br></span><span style="COLOR: #008080">11</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;</span><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;testDefaultSize(self):<br></span><span style="COLOR: #008080">12</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;self.failUnless(self.widget.size()&nbsp;</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #000000">50</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">50</span><span style="COLOR: #000000">),&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">incorrect&nbsp;default&nbsp;size</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">)<br></span><span style="COLOR: #008080">13</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br></span><span style="COLOR: #008080">14</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;</span><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;testResize(self):<br></span><span style="COLOR: #008080">15</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;self.widget.resize(</span><span style="COLOR: #000000">100</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">150</span><span style="COLOR: #000000">)<br></span><span style="COLOR: #008080">16</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;self.failUnless(self.widget.size()&nbsp;</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">&nbsp;(</span><span style="COLOR: #000000">100</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">150</span><span style="COLOR: #000000">),&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">wrong&nbsp;size&nbsp;after&nbsp;resize</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">)</span></div>
<p>Here we have not provided a runTest() method, but have instead provided two different test methods. Class instances will now each run one of the test*() methods, with self.widget created and destroyed separately for each instance. When creating an instance we must specify the test method it is to run. We do this by passing the method name in the constructor:</p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">defaultSizeTestCase&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;WidgetTestCase(</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">testDefaultSize</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">)<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>resizeTestCase&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;WidgetTestCase(</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">testResize</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">)<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span></div>
<p>Test case instances are grouped together according to the features they test. unittest provides a mechanism for this: the test suite, represented by unittest's TestSuite class:</p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">widgetTestSuite&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;unittest.TestSuite()<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>widgetTestSuite.addTest(WidgetTestCase(</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">testDefaultSize</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">))<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>widgetTestSuite.addTest(WidgetTestCase(</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">testResize</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">))</span></div>
<p>For the ease of running tests, as we will see later, it is a good idea to provide in each test module a callable object that returns a pre-built test suite:</p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;suite():<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;suite&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;unittest.TestSuite()<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;suite.addTest(WidgetTestCase(</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">testDefaultSize</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">))<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;suite.addTest(WidgetTestCase(</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">testResize</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">))<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;suite<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span></div>
<p>or even:</p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;suite():<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;tests&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;[</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">testDefaultSize</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">testResize</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">]<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;unittest.TestSuite(map(WidgetTestCase,&nbsp;tests))</span></div>
<p><br>Since it is a common pattern to create a TestCase subclass with many similarly named test functions, unittest provides a TestLoader class that can be used to automate the process of creating a test suite and populating it with individual tests. For example,</p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">suite&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;unittest.TestLoader().loadTestsFromTestCase(WidgetTestCase)</span></div>
<p>will create a test suite that will run WidgetTestCase.testDefaultSize() and WidgetTestCase.testResize(). TestLoader use the 'test' method name prefix to identify test methods automatically.</p>
<p>Note that the order in which the various test cases will be run is determined by sorting the function names with the built-in cmp() function.<br><br>Often it is desirable to group suites of test cases together, so as to run tests for the whole system at once. This is easy, since TestSuite instances can be added to a TestSuite just as TestCase instances can be added to a TestSuite.</p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">suite1&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;module1.TheTestSuite()<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>suite2&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;module2.TheTestSuite()<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>alltests&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;unittest.TestSuite([suite1.&nbsp;suite2])</span></div>
<p>&nbsp;</p>
<p>You can place the definitions of test cases and test suites in the same modules as the code they are to test(such as widget.py), but there are several advantages to placing the test code in a separate module, such as test_widget.py.</p>
<ul>
    <li>The test module can be run standalone from the command line.</li>
    <li>The test code can more easily be separated from shipped code.</li>
    <li>There is less temptation to change test code to fit the code it tests without a good reason.</li>
    <li>Test code should be modified much less frequently than the code it tests.</li>
    <li>Tested code can be refactored more easily.</li>
    <li>Tests for modules written in C must be in separate modules anyway, so why not be consistent?</li>
    <li>If the testing strategy changes, there is no need to change the source code.</li>
</ul>
<img src ="http://www.cnitblog.com/donne/aggbug/39498.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/donne/" target="_blank">Don Li</a> 2008-01-31 11:03 <a href="http://www.cnitblog.com/donne/archive/2008/01/31/39498.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>unittest - Classes and functions</title><link>http://www.cnitblog.com/donne/archive/2008/01/30/39480.html</link><dc:creator>Don Li</dc:creator><author>Don Li</author><pubDate>Wed, 30 Jan 2008 07:26:00 GMT</pubDate><guid>http://www.cnitblog.com/donne/archive/2008/01/30/39480.html</guid><wfw:comment>http://www.cnitblog.com/donne/comments/39480.html</wfw:comment><comments>http://www.cnitblog.com/donne/archive/2008/01/30/39480.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/donne/comments/commentRss/39480.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/donne/services/trackbacks/39480.html</trackback:ping><description><![CDATA[<p>class TestCase([methondName])<br>&nbsp; Instances of the TestCase class represent the smallest testable units in the unittest universe. This class is intended to be used as a base class, with specific tests being implemented by concrete subclasses. This class implements the interface needed by the test runner to allow it to drive the test, and methods that the test code can use to check for and report various kinds of failure. </p>
Each instance of TestCase will run a single test emthod: the method named methodName. If you remember, we had an earlier example that went something like this:
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #008080">1</span><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;suite():<br></span><span style="COLOR: #008080">2</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;suite&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;unittest.TestSuite()<br></span><span style="COLOR: #008080">3</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;suite.addTest(WidgetTestCase(</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">testDefaultSize</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">))<br></span><span style="COLOR: #008080">4</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;suite.addTest(WidgetTestCase(</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">testResize</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">))<br></span><span style="COLOR: #008080">5</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;suite</span></div>
Here, we create two instances of WidgetTestCase, each of which runs a single test.<br>methodName defaults to 'runTest'.<br><br>class FunctionTestCase(testFunc, [, setUp[, tearDown[, description]]])<br>&nbsp; This class implements the portion of the TestCase interface which allows the test runner to drive the test, but does not provide the methods which test code can use to check and report errors. This is used to create test test cases using legacy test code, allowing it to be integrated into a unittest-based test framework.<br><br>class TestSuite([tests])<br>&nbsp; This class represents an aggregation of individual tests cases and test suites. The class presents the interface needed by the test runner to allow it to be run as any other test case. Running a TestSuite instance is the same as iterating over the suite, running each test individually.<br>&nbsp; If tests is given, it must be an iterable of individual test cases or other test suites that will be used to build the suite initially. Additional methods are provided to add test cases and suites to the collection later on.<br><br>class TestLoader()<br>&nbsp; This class is responsible for loading tests according to various criteria and returning them wrapped in a TestSuite. It can load all tests within a given module or TestCase subclass.<br><br>class TestResult()<br>&nbsp; This class is used to compile information about which tests have succeeded and which have failed.<br><br>defaultTestLoader<br>&nbsp; Instance of the TestLoader class intended to be shared. if no customization of the TestLoader is needed, this instance can be used instead of repeatedly creating new instances.<br><br>class TextTestRunner([stream[, descriptions[, verbosity]]])<br>&nbsp; A basic test runner implementation which prints results on standard error. It has a few configurable parameters, but is essentially very simple. Graphical applications which run test suites should provide alternate implementations.<br><br>main([module[, defaultTest[, argv[, testRunner[, testLoader]]]]])<br>&nbsp; A command-line program that runs a set of tests; this primarily for making test modules conveniently executalbe. The simplest use for this function is to include the following line at the end of a test script:<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #008080">1</span><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800080">__name__</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">__main__</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">:<br></span><span style="COLOR: #008080">2</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;unittest.main()</span></div>
<br>In some cases, the existing tests may have been written using the doctest module. If so, that module provides a DocTestSuite class that can automatically build unittest.TestSuite instances from the existing doctest-based tests. new in version 2.3.<br><br><br>
<img src ="http://www.cnitblog.com/donne/aggbug/39480.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/donne/" target="_blank">Don Li</a> 2008-01-30 15:26 <a href="http://www.cnitblog.com/donne/archive/2008/01/30/39480.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>unittest - Basic example</title><link>http://www.cnitblog.com/donne/archive/2008/01/30/39477.html</link><dc:creator>Don Li</dc:creator><author>Don Li</author><pubDate>Wed, 30 Jan 2008 06:07:00 GMT</pubDate><guid>http://www.cnitblog.com/donne/archive/2008/01/30/39477.html</guid><wfw:comment>http://www.cnitblog.com/donne/comments/39477.html</wfw:comment><comments>http://www.cnitblog.com/donne/archive/2008/01/30/39477.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/donne/comments/commentRss/39477.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/donne/services/trackbacks/39477.html</trackback:ping><description><![CDATA[The unittest module provides a rich set of tools for constructing and running tests. This section demonstrates that a small subset of the tools suffice to meet the needs of most users.<br><br>Here is a short script to test three functions from the random module:<br>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #008080">&nbsp;1</span><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000">&nbsp;random<br></span><span style="COLOR: #008080">&nbsp;2</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000">&nbsp;unittest<br></span><span style="COLOR: #008080">&nbsp;3</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br></span><span style="COLOR: #008080">&nbsp;4</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;TestSequenceFunctions(unittest.TestCase):<br></span><span style="COLOR: #008080">&nbsp;5</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;</span><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;setUp(self):<br></span><span style="COLOR: #008080">&nbsp;6</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;self.seq&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;range(</span><span style="COLOR: #000000">10</span><span style="COLOR: #000000">)<br></span><span style="COLOR: #008080">&nbsp;7</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;<br></span><span style="COLOR: #008080">&nbsp;8</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;</span><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;testshuffle(self):<br></span><span style="COLOR: #008080">&nbsp;9</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">#</span><span style="COLOR: #008000">make&nbsp;sure&nbsp;the&nbsp;shuffled&nbsp;sequence&nbsp;does&nbsp;not</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">10</span><span style="COLOR: #008000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #008000">#</span><span style="COLOR: #008000">lose&nbsp;any&nbsp;elements</span><span style="COLOR: #008000"><br></span><span style="COLOR: #008080">11</span><span style="COLOR: #008000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #000000">&nbsp;&nbsp;&nbsp;&nbsp;random.shuffle(self.seq)<br></span><span style="COLOR: #008080">12</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;self.seq.sort()<br></span><span style="COLOR: #008080">13</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;self.assertEqual(self.seq,&nbsp;range(</span><span style="COLOR: #000000">10</span><span style="COLOR: #000000">))<br></span><span style="COLOR: #008080">14</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br></span><span style="COLOR: #008080">15</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;</span><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;testchoice(self):<br></span><span style="COLOR: #008080">16</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;element&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;random.choice(self.seq)<br></span><span style="COLOR: #008080">17</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;self.assert_(element&nbsp;</span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000">&nbsp;self.seq)<br></span><span style="COLOR: #008080">18</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br></span><span style="COLOR: #008080">19</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;</span><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;testsample(self):<br></span><span style="COLOR: #008080">20</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;self.assertRaises(ValueError,&nbsp;random.sample,&nbsp;self.seq,&nbsp;</span><span style="COLOR: #000000">20</span><span style="COLOR: #000000">)<br></span><span style="COLOR: #008080">21</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;element&nbsp;</span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000">&nbsp;random.sample(self.seq,&nbsp;</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">):<br></span><span style="COLOR: #008080">22</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.assert_(element&nbsp;</span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000">&nbsp;self.seq)<br></span><span style="COLOR: #008080">23</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br></span><span style="COLOR: #008080">24</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800080">__name__</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">__main__</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">:<br></span><span style="COLOR: #008080">25</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;unittest.main()<br></span><span style="COLOR: #008080">26</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span></div>
<p><br>A testcase is created by subclassing unittest.TestCase. The thress individual tests are defined with methods whose names start with the letters "test". This nameing convention informs the test runner about which methods represent tests.<br>The crux of each tests is a call to assertEqual() to check for an expected result; assert_() to verify a condition; or assertRaises() to verify that an expected exception gets raised. These methods are used instead of the assert statement so the test runner can accumulate all test results and produce a report.<br>When a setUp() method is defined, the test runner will run that method prior to each test. Likewise, if a tearDown() method is defined, the test runner wil invoke that method after each test. In the example,setUp() was used to create a fresh sequence for each test.<br>The final block shows a simple way to run the tests. unittest.main() provides a command line interface to the test script. When run from the command line, the above script produces an output that looks like this:<br>...<br>----------------------------------------------------------------------<br>Ran 3 tests in 0.000s</p>
<p>OK<br><br>Instead of unittest.main(), there are other ways to run the tests with a finer level of control, less terse output, and no requirement to be run from the command line. For example, the last two line may be replaced with:</p>
<p>&nbsp;</p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #000000">suite&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;unittest.TestLoader().loadTestsFromTestCase(TestSequenceFunctions)<br><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>unittest.TextTestRunner(verbosity</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">).run(suite)</span></div>
<p>Running the revised script from the interpreter or another script produces the following output:<br>testchoice (__main__.TestSequenceFunctions) ... ok<br>testsample (__main__.TestSequenceFunctions) ... ok<br>testshuffle (__main__.TestSequenceFunctions) ... ok<br><br>----------------------------------------------------------------------<br>Ran 3 tests in 0.110s<br><br>OK<br><br>The above examples show the most commonly used unittest features which are sufficient to meet many everyday testing needs. The remainder of the documentation explores the full feature set from first principles.<br><br><br></p>
<img src ="http://www.cnitblog.com/donne/aggbug/39477.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/donne/" target="_blank">Don Li</a> 2008-01-30 14:07 <a href="http://www.cnitblog.com/donne/archive/2008/01/30/39477.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>unittest - Unit testing framework</title><link>http://www.cnitblog.com/donne/archive/2008/01/30/python.html</link><dc:creator>Don Li</dc:creator><author>Don Li</author><pubDate>Wed, 30 Jan 2008 02:54:00 GMT</pubDate><guid>http://www.cnitblog.com/donne/archive/2008/01/30/python.html</guid><wfw:comment>http://www.cnitblog.com/donne/comments/39472.html</wfw:comment><comments>http://www.cnitblog.com/donne/archive/2008/01/30/python.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/donne/comments/commentRss/39472.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/donne/services/trackbacks/39472.html</trackback:ping><description><![CDATA[New in version 2.1<br><br>The Python unit testing framework, sometimes referred to as 'PyUnit', is a Python language version of JUnit, by Kent Beck and Erich Gamma. JUnit is, in turn, a Java version of Kent's Smalltalk testing framework. Each is the de facto standard unit testing framework for its respective language.<br>unittest supports test automation, sharing of setup and shutdown code for tests, aggregation of tests into collections, and independence of the tests from the reporting framework. The unittest module provides classes that make it easy to support these qualities for a set of tests.<br>To achieve this, unittest supports some important concepts:<br>test fixture<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A test fixture represents the preparation needed to perform one or more tests, and any associate cleanup actions. This may involve, for example, creating temporary or proxy databases, directories, or starting a server process.<br><br>test case<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A test case is the smallest unit of tesing. It checks for a specific response to a particular set of inputs. unittest provies a base class, TestCase, which may be used to create new test cases.<br><br>test suite<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A test suite is collection of test cases, test suites, or both. It is used to aggregate tests that should be executed together. <br><br>test runner<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A test runner is a component which orchestrates the execution of tests and provides the outcome to the user. The runner may use a graphical interface, a textual interface, or return a special value to indicate the results of executing the tests.<br><br>The test case and test fixture concepts are supported through the TestCase and FunctionTestCase classes; the former should be used when creating new tests. and the latter can be used when integrating existing test code with a unittest-driven framework. When building test fixtures using TestCase, the setUp() and tearDown() methods can be overridden to provide initialization and cleanup for the fixture. With FunctionTestCase, existing functions can be passed to the constructor for these purposes. When the test is run, the fixture initialization is run first; if it succeeds, the cleanup method is run after the test has been executed, regardless of the outcome of the test. Each instance of the TestCase will only be used to run a single test method, so a new fixture is created for each test.<br><br>The suites are implemeted by the TestSuite class. This class allows individual tests and test suites to be aggregated; when the suite is executed, all tests added directly to the suite and in 'child' test suites are run.<br><br>A test runner is an object thtat provides a&nbsp;single method, run(), which accepts a TestCase or TestSuite object as a parameter, and returns a result object. The class TestResult is provided for use as the result object. unittest provides the TextTestRunner as an example test runner which reports test results on the standard error stream by default. Alternate runners can be implemented for other environments(such as graphical environments) without any need to derive from a specific class.
<img src ="http://www.cnitblog.com/donne/aggbug/39472.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/donne/" target="_blank">Don Li</a> 2008-01-30 10:54 <a href="http://www.cnitblog.com/donne/archive/2008/01/30/python.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>搜索结果的死链分析</title><link>http://www.cnitblog.com/donne/archive/2007/12/05/37368.html</link><dc:creator>Don Li</dc:creator><author>Don Li</author><pubDate>Wed, 05 Dec 2007 10:42:00 GMT</pubDate><guid>http://www.cnitblog.com/donne/archive/2007/12/05/37368.html</guid><wfw:comment>http://www.cnitblog.com/donne/comments/37368.html</wfw:comment><comments>http://www.cnitblog.com/donne/archive/2007/12/05/37368.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/donne/comments/commentRss/37368.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/donne/services/trackbacks/37368.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 用到的函数 URLsParser.py:from&nbsp;sgmllib&nbsp;import&nbsp;SGMLParser,&nbsp;SGMLParseErrorimport&nbsp;urllibimport&nbsp;urlparseimport&nbsp;time,&nbsp;sysclass&nbsp;URLLister(SGMLParser):&nbsp;&nbsp;&nb...&nbsp;&nbsp;<a href='http://www.cnitblog.com/donne/archive/2007/12/05/37368.html'>阅读全文</a><img src ="http://www.cnitblog.com/donne/aggbug/37368.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/donne/" target="_blank">Don Li</a> 2007-12-05 18:42 <a href="http://www.cnitblog.com/donne/archive/2007/12/05/37368.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Python线程编程</title><link>http://www.cnitblog.com/donne/archive/2007/12/04/37319.html</link><dc:creator>Don Li</dc:creator><author>Don Li</author><pubDate>Tue, 04 Dec 2007 08:27:00 GMT</pubDate><guid>http://www.cnitblog.com/donne/archive/2007/12/04/37319.html</guid><wfw:comment>http://www.cnitblog.com/donne/comments/37319.html</wfw:comment><comments>http://www.cnitblog.com/donne/archive/2007/12/04/37319.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnitblog.com/donne/comments/commentRss/37319.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/donne/services/trackbacks/37319.html</trackback:ping><description><![CDATA[<p>我们在做软件开发的时候很多要用到多线程技术。例如如果做一个下载软件象flashget就要用到、象在线视频工具realplayer也要用到因为要同时下载media stream还要播放。其实例子是很多的。</p>
<p>线程相对进程来说是&#8220;轻量级&#8221;的，操作系统用较少的资源创建和管理线程。程序中的线程在相同的内存空间中执行，并共享许多相同的资源。</p>
<p>在<font color=#99cc00>python</font>中如何创建一个线程对象</p>
<p>如果你要创建一个线程对象，很简单，只要你的类继承<font color=#99cc00>threading.Thread</font>，然后在<font color=#99cc00>__init__</font>里首先调用<font color=#99cc00>threading.Thread</font>的<font color=#99cc00>__init__</font>方法即可</p>
<p><font color=#99cc00>import threading<br>class mythread(threading.Thread):<br>def __init__(self, threadname):<br>threading.Thread.__init__(self, name = threadname)<br>....</font></p>
<p>这才仅仅是个空线程，我可不是要他拉空车的，他可得给我干点实在活。很简单，重写类的<font color=#99cc00>run()</font>方法即可，把你要在线程执行时做的事情都放到里面</p>
<p><font color=#99cc00>import threading<br>import time<br>class mythread(threading.Thread):<br>def __init__(...):<br>....<br>def run(self):<br>for i in range(10):<br>print self.getName, i<br>time.sleep(1)</font></p>
<p>以上代码我们让这个线程在执行之后每隔1秒输出一次信息到屏幕，10次后结束</p>
<p><font color=#99cc00>getName()</font>是<font color=#99cc00>threading.Thread</font>类的一个方法，用来获得这个线程对象的<font color=#99cc00>name</font>。还有一个方法<font color=#99cc00>setName()</font>当然就是来设置这个线程对象的<font color=#99cc00>name</font>的了。</p>
<p>如果要创建一个线程，首先就要先创建一个线程对象</p>
<p><font color=#99cc00>mythread1 = mythread('mythread 1')</font></p>
<p>一个线程对象被创建后，他就处于&#8220;<font color=#99cc00>born</font>&#8221;（诞生状态）</p>
<p>如何让这个线程对象开始运行呢?只要调用线程对象的<font color=#99cc00>start()</font>方法即可</p>
<p><font color=#99cc00>mythread1.start()</font></p>
<p>现在线程就处于&#8220;<font color=#99cc00>ready</font>&#8221;状态或者也称为&#8220;<font color=#99cc00>runnable</font>&#8221;状态。</p>
<p>奇怪吗？不是已经<font color=#99cc00>start</font>了吗？为什么不称为&#8220;<font color=#99cc00>running</font>&#8221;状态呢？其实是有原因的。因为我们的计算机一般是不具有真正并行处理能力的。我们所谓的多线程只是把时间分成片段，然后隔一个时间段就让一个线程执行一下，然后进入&#8220;<font color=#99cc00>sleeping</font> &#8221;状态，然后唤醒另一个在&#8220;<font color=#99cc00>sleeping</font>&#8221;的线程，如此循环<font color=#99cc00>runnable-&gt;sleeping-&gt;runnable...</font> ，只是因为计算机执行速度很快，而时间片段间隔很小，我们感受不到，以为是同时进行的。所以说一个线程在<font color=#99cc00>start</font>了之后只是处在了可以运行的状态，他什么时候运行还是由系统来进行调度的。</p>
<p>那一个线程什么时候会&#8220;<font color=#99cc00>dead</font>&#8221;呢？一般来说当线程对象的<font color=#99cc00>run</font>方法执行结束或者在执行中抛出异常的话，那么这个线程就会结束了。系统会自动对&#8220;<font color=#99cc00>dead</font>&#8221;状态线程进行清理。</p>
<p>如果一个线程<font color=#99cc00>t1</font>在执行的过程中需要等待另一个线程<font color=#99cc00>t2</font>执行结束后才能运行的话那就可以在<font color=#99cc00>t1</font>在调用<font color=#99cc00>t2</font>的<font color=#99cc00>join()</font>方法</p>
<p><font color=#99cc00>....<br>def t1(...):<br>...<br>t2.join()<br>...</font></p>
<p>这样<font color=#99cc00>t1</font>在执行到<font color=#99cc00>t2.join()</font>语句后就会等待<font color=#99cc00>t2</font>结束后才会继续运行。</p>
<p>但是假如<font color=#99cc00>t1</font>是个死循环的话那么等待就没有意义了，那怎么办呢？可以在调用<font color=#99cc00>t2</font>的<font color=#99cc00>join()</font>方法的时候给一个浮点数做超时参数，这样这个线程就不会等到花儿也谢了了。我等你10s，你不回来我还不允许我改嫁啊？<font color=#ff0000>:)</font></p>
<p><font color=#99cc00>def t1(...):<br>...<br>t2.join(10)<br>...</font></p>
<p>如果一个进程的主线程运行完毕而子线程还在执行的话，那么进程就不会退出，直到所有子线程结束为止，如何让主线程结束的时候其他子线程也乖乖的跟老大撤退呢？那就要把那些不听话的人设置为听话的小弟，使用线程对象的<font color=#99cc00>setDaemon()</font>方法，参数为<font color=#99cc00>bool</font>型。<font color=#99cc00>True</font>的话就代表你要听话，我老大（主线程）扯呼，你也要跟着撤，不能拖后腿。如果是<font color=#99cc00>False</font>的话就不用那么听话了，老大允许你们将在外军命有所不受的。需要注意的是<font color=#99cc00>setDaemon()</font>方法必须在线程对象没有调用<font color=#99cc00>start()</font>方法之前调用，否则没效果。</p>
<p><font color=#99cc00>t1 = mythread('t1')<br>print t1.getName(),t1.isDaemon()<br>t1.setDaemon(True)<br>print t1.getName(),t1.isDaemon()<br>t1.start()<br>print 'main thread exit'</font></p>
<p>当执行到 <font color=#99cc00>print 'main thread exit' </font>后，主线程就退出了，当然<font color=#99cc00>t1</font>这个线程也跟着结束了。但是如果不使用<font color=#99cc00>t1</font>线程对象的<font color=#99cc00>setDaemon()</font>方法的话，即便主线程结束了，还要等待t1线程自己结束才能退出进程。<font color=#99cc00>isDaemon()</font>是用来获得一个线程对象的<font color=#99cc00>Daemonflag</font>状态的。</p>
<p>如何来获得与线程有关的信息呢？</p>
<p>获得当前正在运行的线程的引用</p>
<p><font color=#99cc00>running = threading.currentThread()</font></p>
<p>获得当前所有活动对象（即<font color=#99cc00>run</font>方法开始但是未终止的任何线程）的一个列表</p>
<p><font color=#99cc00>threadlist = threading.enumerate()</font></p>
<p>获得这个列表的长度</p>
<p><font color=#99cc00>threadcount = threading.activeCount()</font></p>
<p>查看一个线程对象的状态调用这个线程对象的<font color=#99cc00>isAlive()</font>方法，返回1代表处于&#8220;<font color=#99cc00>runnable</font>&#8221;状态且没有&#8220;<font color=#99cc00>dead</font>&#8221;</p>
<p><font color=#99cc00>threadflag = threading.isAlive()</font><br></p>
<p><br><br></p>
<p>&nbsp;</p>
<p><br><br></p>
<div><br>
<h5><strong>Python线程编程（二）简单的线程同步</strong></h5>
<br><br>
<p><br>&nbsp;&nbsp;&nbsp; 多个执行线程经常要共享数据，如果仅仅读取共享数据还好，但是如果多个线程要修改共享数据的话就可能出现无法预料的结果。</p>
<p>&nbsp;&nbsp;&nbsp; 假如两个线程对象<font color=#ff6600>t1</font>和<font color=#ff6600>t2</font>都要对数值<font color=#ff6600>num=0</font>进行增1运算，那么<font color=#ff6600>t1</font>和<font color=#ff6600>t2</font>都各对<font color=#ff6600>num</font>修改<font color=#ff6600>10</font>次的话，那么<font color=#ff6600>num</font>最终的结果应该为<font color=#ff6600>20</font>。但是如果当<font color=#ff6600>t1</font>取得<font color=#ff6600>num</font>的值时（假如此时<font color=#ff6600>num</font>为<font color=#ff6600>0</font>），系统把<font color=#ff6600>t1</font>调度为&#8220;<font color=#ff6600>sleeping</font>&#8221;状态，而此时<font color=#ff6600>t2</font>转换为&#8220;<font color=#ff6600>running</font>&#8221;状态，此时<font color=#ff6600>t2</font>获得的<font color=#ff6600>num</font>的值也为<font color=#ff6600>0</font>，然后他把<font color=#ff6600>num+1</font>的值<font color=#ff6600>1</font>赋给<font color=#ff6600>num</font>。系统又把<font color=#ff6600>t2</font>转化为&#8220;<font color=#ff6600>sleeping</font>&#8221;状态，<font color=#ff6600>t1</font>为&#8220;<font color=#ff6600>running</font>&#8221;状态，由于<font color=#ff6600>t1</font>已经得到<font color=#ff6600>num</font>值为<font color=#ff6600>0</font>，所以他也把<font color=#ff6600>num+1</font>的值赋给了<font color=#ff6600>num</font>为<font color=#ff6600>1</font>。本来是<font color=#ff6600>2</font>次增<font color=#ff6600>1</font>运行，结果却是<font color=#ff6600>num</font>只增了<font color=#ff6600>1</font>次。类似这样的情况在多线程同时执行的时候是有可能发生的。所以为了防止这类情况的出现就要使用线程同步机制。</p>
<p>&nbsp;&nbsp;&nbsp; 最简单的同步机制就是&#8220;锁&#8221;</p>
<p>&nbsp;&nbsp;&nbsp; 锁对象用<font color=#ff6600>threading.RLock</font>类创建</p>
<p>&nbsp;&nbsp;&nbsp; <font color=#ff6600>mylock = threading.RLock()</font></p>
<p>&nbsp;&nbsp;&nbsp; 如何使用锁来同步线程呢？线程可以使用锁的<font color=#ff6600>acquire()</font> （获得）方法，这样锁就进入&#8220;<font color=#ff6600>locked</font>&#8221;状态。每次只有一个线程可以获得锁。如果当另一个线程试图获得这个锁的时候，就会被系统变为&#8220;<font color=#ff6600>blocked</font>&#8221;状态，直到那个拥有锁的线程调用锁的<font color=#ff6600>release()</font> （释放）方法，这样锁就会进入&#8220;<font color=#ff6600>unlocked</font>&#8221;状态。&#8220;<font color=#ff6600>blocked</font>&#8221;状态的线程就会收到一个通知，并有权利获得锁。如果多个线程处于&#8220;<font color=#ff6600>blocked</font>&#8221;状态，所有线程都会先解除&#8220;<font color=#ff6600>blocked</font>&#8221;状态，然后系统选择一个线程来获得锁，其他的线程继续沉默（&#8220;<font color=#ff6600>blocked</font>&#8221;）。</p>
<p><font color=#ff6600>import threading<br>mylock = threading.RLock()<br>class mythread(threading.Thread)<br>&nbsp;&nbsp;&nbsp; ...<br>&nbsp;&nbsp;&nbsp; def run(self ...):<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...&nbsp;&nbsp;&nbsp;&nbsp; <font color=#3366ff>#此处 <font color=#ff00ff>不可以 </font>放置修改共享数据的代码<br></font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mylock.acquire()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...&nbsp;&nbsp;&nbsp;&nbsp; <font color=#3366ff>#此处 <font color=#ff00ff>可以 </font>放置修改共享数据的代码<br></font>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mylock.release()<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...&nbsp;&nbsp;&nbsp;&nbsp; </font><font color=#3366ff>#此处 <font color=#ff00ff>不可以 </font>放置修改共享数据的代码</font></p>
<p>&nbsp;&nbsp;&nbsp; 我们把修改共享数据的代码称为&#8220;临界区&#8221;，必须将所有&#8220;临界区&#8221;都封闭在同一锁对象的<font color=#ff6600>acquire()</font>和<font color=#ff6600>release()</font>方法调用之间。</p>
<p>&nbsp;&nbsp;&nbsp; 锁只能提供最基本的同步级别。有时需要更复杂的线程同步，例如只在发生某些事件时才访问一个临界区（例如当某个数值改变时）。这就要使用&#8220;条件变量&#8221;。</p>
<p>&nbsp;&nbsp;&nbsp; 条件变量用<font color=#ff6600>threading.Condition</font>类创建</p>
<p>&nbsp;&nbsp;&nbsp; <font color=#ff6600>mycondition = threading.Condition()</font></p>
<p>&nbsp;&nbsp;&nbsp; 条件变量是如何工作的呢？首先一个线程成功获得一个条件变量后，调用此条件变量的<font color=#ff6600>wait()</font>方法会导致这个线程释放这个锁，并进入&#8220;<font color=#ff6600>blocked</font>&#8221;状态，直到另一个线程调用同一个条件变量的<font color=#ff6600>notify()</font>方法来唤醒那个进入&#8220;<font color=#ff6600>blocked</font>&#8221;状态的线程。如果调用这个条件变量的<font color=#ff6600>notifyAll()</font>方法的话就会唤醒所有的在等待的线程。</p>
<p>&nbsp;&nbsp;&nbsp; 如果程序或者线程永远处于&#8220;<font color=#ff6600>blocked</font>&#8221;状态的话，就会发生死锁。所以如果使用了锁、条件变量等同步机制的话，一定要注意仔细检查，防止死锁情况的发生。对于可能产生异常的临界区要使用异常处理机制中的<font color=#ff6600>finally</font>子句来保证释放锁。等待一个条件变量的线程必须用<font color=#ff6600>notify()</font>方法显式的唤醒，否则就永远沉默。保证每一个<font color=#ff6600>wait()</font>方法调用都有一个相对应的<font color=#ff6600>notify()</font>调用，当然也可以调用<font color=#ff6600>notifyAll()</font>方法以防万一。</p>
<br><br></div>
<p><br></p>
<p>&nbsp;</p>
<p><br></p>
<div><br>
<h5><strong>Python线程编程（三）同步队列</strong></h5>
<br><br>
<p><br>我们经常会采用生产者/消费者关系的两个线程来处理一个共享缓冲区的数据。例如一个生产者线程接受用户数据放入一个共享缓冲区里，等待一个消费者线程对数据取出处理。但是如果缓冲区的太小而生产者和消费者两个异步线程的速度不同时，容易出现一个线程等待另一个情况。为了尽可能的缩短共享资源并以相同速度工作的各线程的等待时间，我们可以使用一个&#8220;队列&#8221;来提供额外的缓冲区。<br><br>创建一个&#8220;队列&#8221;对象<br><br><font color=#ff9900>import Queue<br>myqueue = Queue.Queue(maxsize = 10)<br><br></font><font color=#ff9900>Queue.Queue</font>类即是一个队列的同步实现。队列长度可为无限或者有限。可通过<font color=#ff9900>Queue</font>的构造函数的可选参数<font color=#ff9900>maxsize</font>来设定队列长度。如果<font color=#ff9900>maxsize</font>小于<font color=#ff9900>1</font>就表示队列长度无限。<br><br>将一个值放入队列中<br><br><font color=#ff9900>myqueue.put(10)<br></font><br>调用队列对象的<font color=#ff9900>put()</font>方法在队尾插入一个项目。<font color=#ff9900>put()</font>有两个参数，第一个<font color=#ff9900>item</font>为必需的，为插入项目的值；第二个<font color=#ff9900>block</font>为可选参数，默认为<font color=#ff9900>1</font>。如果队列当前为空且<font color=#ff9900>block</font>为<font color=#ff9900>1</font>，<font color=#ff9900>put()</font>方法就使调用线程暂停,直到空出一个数据单元。如果<font color=#ff9900>block</font>为<font color=#ff9900>0</font>，<font color=#ff9900>put</font>方法将引发<font color=#ff9900>Full</font>异常。<br><br>将一个值从队列中取出<br><br><font color=#ff9900>myqueue.get()<br></font><br>调用队列对象的<font color=#ff9900>get()</font>方法从队头删除并返回一个项目。可选参数为<font color=#ff9900>block</font>，默认为<font color=#ff9900>1</font>。如果队列为空且<font color=#ff9900>block</font>为<font color=#ff9900>1</font>，<font color=#ff9900>get()</font>就使调用线程暂停，直至有项目可用。如果<font color=#ff9900>block</font>为0，队列将引发<font color=#ff9900>Empty</font>异常。<br><br>我们用一个例子来展示如何使用<font color=#ff9900>Queue<br><br></font><font color=#ff9900># queue_example.py<br>from Queue import Queue<br>import threading<br>import random<br>import time</font></p>
<p><font color=#ff9900># Producer thread<br>class Producer(threading.Thread):<br>def __init__(self, threadname, queue):<br>threading.Thread.__init__(self, name = threadname)<br>self.sharedata = queue<br>def run(self):<br>for i in range(20):<br>print self.getName(),'adding',i,'to queue'<br>self.sharedata.put(i)<br>time.sleep(random.randrange(10)/10.0)<br>print self.getName(),'Finished'</font></p>
<p><font color=#ff9900># Consumer thread<br>class Consumer(threading.Thread):<br>def __init__(self, threadname, queue):<br>threading.Thread.__init__(self, name = threadname)<br>self.sharedata = queue<br>def run(self):<br>for i in range(20):<br>print self.getName(),'got a value:',self.sharedata.get()<br>time.sleep(random.randrange(10)/10.0)<br>print self.getName(),'Finished'</font></p>
<p><font color=#ff9900># Main thread<br>def main():<br>queue = Queue()<br>producer = Producer('Producer', queue)<br>consumer = Consumer('Consumer', queue)</font></p>
<p><font color=#ff9900>print 'Starting threads ...'<br>producer.start()<br>consumer.start()</font></p>
<p><font color=#ff9900>producer.join()<br>consumer.join()</font></p>
<p><font color=#ff9900>print 'All threads have terminated.'</font></p>
<p><font color=#ff9900>if __name__ == '__main__':<br>main()</font></p>
<p>示例代码中实现了两个类：生产者类<font color=#ff9900>Producer</font>和消费者类<font color=#ff9900>Consumer</font>。前者在一个随机的时间内放入一个值到队列<font color=#ff9900>queue</font>中然后显示出来，后者在一定随机的时间内从队列<font color=#ff9900>queue</font>中取出一个值并显示出来。</p>
</div>
<img src ="http://www.cnitblog.com/donne/aggbug/37319.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/donne/" target="_blank">Don Li</a> 2007-12-04 16:27 <a href="http://www.cnitblog.com/donne/archive/2007/12/04/37319.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>UltraEdit32的Python语法着色</title><link>http://www.cnitblog.com/donne/archive/2007/12/04/37316.html</link><dc:creator>Don Li</dc:creator><author>Don Li</author><pubDate>Tue, 04 Dec 2007 06:51:00 GMT</pubDate><guid>http://www.cnitblog.com/donne/archive/2007/12/04/37316.html</guid><wfw:comment>http://www.cnitblog.com/donne/comments/37316.html</wfw:comment><comments>http://www.cnitblog.com/donne/archive/2007/12/04/37316.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/donne/comments/commentRss/37316.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/donne/services/trackbacks/37316.html</trackback:ping><description><![CDATA[/L10"Python" PYTHON_LANG Line Comment = #&nbsp; Escape Char = \ File Extensions = PY PYW<br>/Indent Strings = ":"<br>/Function String 1 = "%[ ,^t]++def[ ]+^([a-zA-Z0-9_]+*^):"<br>/Function String 2 = "%[ ,^t]++^(class[ ]+[a-zA-Z0-9_]+*^):"<br>/Open Brace String = "(" "["<br>/Close Brace String = ")" "]"<br>/Delimiters =&nbsp; []{}()&lt;&gt;="'.,:+<br>/C1"Reserved Words"<br>and assert<br>break<br>class continue<br>def del<br>elif else except exec<br>finally for from<br>global<br>if import in is<br>lambda<br>map<br>not<br>None<br>or<br>pass print<br>raise range return<br>try<br>while<br>/C2"Built-in Functions"<br>abs apply<br>callable chr cmp coerce compile complex<br>delattr dir divmod<br>eval execfile<br>filter float<br>getattr globals group<br>hasattr hash hex<br>id input int intern isinstance issubclass<br>joinfields<br>len list local long<br>max min match<br>oct open ord<br>pow<br>raw_input reduce reload repr round<br>search setattr setdefault slice str splitfields<br>unichr unicode<br>tuple type<br>vars<br>xrange<br>zip<br>__import__<br>/C3"__Methods__"<br>__abs__ __add__ __and__<br>__call__ __cmp__ __coerce__<br>__del__ __delattr__ __delitem__ __delslice__ __div__ __divmod__<br>__float__<br>__getattr__ __getitem__ __getslice__<br>__hash__ __hex__<br>__iadd__ __isub__ __imod__ __idiv__ __ipow__ __iand__ __ior__ __ixor__<br>__ilshift__ __irshift__<br>__invert__ __int__ __init__<br>__len__ __long__ __lshift__<br>__mod__ __mul__<br>__neg__ __nonzero__<br>__oct__ __or__<br>__pos__ __pow__<br>__radd__ __rdiv__ __rdivmod__ __rmod__ __rpow__ __rlshift__ __rrshift__<br>__rshift__ __rsub__ __rmul__ __repr__<br>__rand__ __rxor__ __ror__<br>__setattr__ __setitem__ __setslice__ __str__ __sub__<br>__xor__<br>/C4"__Attributes__"<br>__author__<br>__bases__<br>__class__ __copyright__<br>__date__ __dict__ __doc__<br>__license__<br>__methods__ __members__<br>__name__<br>__version__<br>/C5"Exceptions"<br>ArithmeticError AssertionError AttributeError<br>EOFError Exception<br>FloatingPointError<br>IOError ImportError IndentationError IndexError<br>KeyError KeyboardInterrupt<br>LookupError<br>MemoryError<br>NameError<br>OverflowError<br>RuntimeError<br>StandardError SyntaxError SystemError SystemExit<br>TabError TypeError<br>ValueError<br>ZeroDivisionError<br>/C6"Operators"<br>+=<br>-=<br>%=<br>/=<br>**=<br>&amp;=<br>|=<br>^=<br>&gt;&gt;=<br>&lt;&lt;=<br>/C7"Common Libs"<br>AST atexit<br>BaseHTTPServer Bastion<br>cmd codecs commands compileall copy<br>CGIHTTPServer Complex<br>dbhash dircmp dis dospath dumbdbm<br>emacs<br>find fmt fnmatch ftplib<br>getopt glob gopherlib grep<br>htmllib httplib<br>ihooks imghdr imputil<br>linecache lockfile<br>macpath macurl2path mailbox mailcap<br>mimetools mimify mutex math<br>Mimewriter<br>newdir ni nntplib ntpath nturl2path<br>os ospath<br>pdb pickle pipes poly popen2 posixfile posixpath profile pstats pyclbr<br>pyexpat<br>Para<br>quopri<br>Queue<br>rand random regex regsub rfc822<br>sched sgmllib shelve site sndhdr string sys snmp<br>SimpleHTTPServer StringIO SocketServer<br>tb tempfile toaiff token tokenize traceback tty types tzparse<br>Tkinter<br>unicodedata urllib urlparse util uu<br>UserDict UserList<br>wave webbrowser whatsound whichdb whrandom<br>xdrlib xml xmlpackage<br>zmod<br>/C8"Others"<br>array<br>fnmatch<br>struct self<br><br><br>把L10改为空闲的即可.
<img src ="http://www.cnitblog.com/donne/aggbug/37316.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/donne/" target="_blank">Don Li</a> 2007-12-04 14:51 <a href="http://www.cnitblog.com/donne/archive/2007/12/04/37316.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>网站死链分析脚本(多线程)</title><link>http://www.cnitblog.com/donne/archive/2007/12/04/37314.html</link><dc:creator>Don Li</dc:creator><author>Don Li</author><pubDate>Tue, 04 Dec 2007 05:52:00 GMT</pubDate><guid>http://www.cnitblog.com/donne/archive/2007/12/04/37314.html</guid><wfw:comment>http://www.cnitblog.com/donne/comments/37314.html</wfw:comment><comments>http://www.cnitblog.com/donne/archive/2007/12/04/37314.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/donne/comments/commentRss/37314.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/donne/services/trackbacks/37314.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 1. URLsParser.py:from&nbsp;sgmllib&nbsp;import&nbsp;SGMLParser,&nbsp;SGMLParseErrorimport&nbsp;urllibimport&nbsp;urlparseimport&nbsp;time,&nbsp;sysclass&nbsp;URLLister(SGMLParser):&nbsp;&nbsp;&nbsp;...&nbsp;&nbsp;<a href='http://www.cnitblog.com/donne/archive/2007/12/04/37314.html'>阅读全文</a><img src ="http://www.cnitblog.com/donne/aggbug/37314.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/donne/" target="_blank">Don Li</a> 2007-12-04 13:52 <a href="http://www.cnitblog.com/donne/archive/2007/12/04/37314.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>ADT in Python</title><link>http://www.cnitblog.com/donne/archive/2007/12/03/37274.html</link><dc:creator>Don Li</dc:creator><author>Don Li</author><pubDate>Mon, 03 Dec 2007 08:04:00 GMT</pubDate><guid>http://www.cnitblog.com/donne/archive/2007/12/03/37274.html</guid><wfw:comment>http://www.cnitblog.com/donne/comments/37274.html</wfw:comment><comments>http://www.cnitblog.com/donne/archive/2007/12/03/37274.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/donne/comments/commentRss/37274.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/donne/services/trackbacks/37274.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: ADT in Python&nbsp;&nbsp;<a href='http://www.cnitblog.com/donne/archive/2007/12/03/37274.html'>阅读全文</a><img src ="http://www.cnitblog.com/donne/aggbug/37274.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/donne/" target="_blank">Don Li</a> 2007-12-03 16:04 <a href="http://www.cnitblog.com/donne/archive/2007/12/03/37274.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>分析巨文本信息的一段代码</title><link>http://www.cnitblog.com/donne/archive/2007/12/03/37258.html</link><dc:creator>Don Li</dc:creator><author>Don Li</author><pubDate>Mon, 03 Dec 2007 01:44:00 GMT</pubDate><guid>http://www.cnitblog.com/donne/archive/2007/12/03/37258.html</guid><wfw:comment>http://www.cnitblog.com/donne/comments/37258.html</wfw:comment><comments>http://www.cnitblog.com/donne/archive/2007/12/03/37258.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnitblog.com/donne/comments/commentRss/37258.html</wfw:commentRss><trackback:ping>http://www.cnitblog.com/donne/services/trackbacks/37258.html</trackback:ping><description><![CDATA[<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img id=Code_Closed_Image_094254 onclick="this.style.display='none'; Code_Closed_Text_094254.style.display='none'; Code_Open_Image_094254.style.display='inline'; Code_Open_Text_094254.style.display='inline';" height=16 src="http://www.cnitblog.com/Images/OutliningIndicators/ContractedBlock.gif" width=11 align=top><img id=Code_Open_Image_094254 style="DISPLAY: none" onclick="this.style.display='none'; Code_Open_Text_094254.style.display='none'; Code_Closed_Image_094254.style.display='inline'; Code_Closed_Text_094254.style.display='inline';" height=16 src="http://www.cnitblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" width=11 align=top><span id=Code_Closed_Text_094254 style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"></span><span id=Code_Open_Text_094254 style="DISPLAY: none"><br><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="COLOR: #008080">&nbsp;1</span><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000">&nbsp;urlparse,&nbsp;csv<br></span><span style="COLOR: #008080">&nbsp;2</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000">&nbsp;threading<br></span><span style="COLOR: #008080">&nbsp;3</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">from</span><span style="COLOR: #000000">&nbsp;operator&nbsp;</span><span style="COLOR: #0000ff">import</span><span style="COLOR: #000000">&nbsp;itemgetter<br></span><span style="COLOR: #008080">&nbsp;4</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br></span><span style="COLOR: #008080">&nbsp;5</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>DICTHOSTS&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;{}<br></span><span style="COLOR: #008080">&nbsp;6</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br></span><span style="COLOR: #008080">&nbsp;7</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">class</span><span style="COLOR: #000000">&nbsp;CSVReader(threading.Thread):<br></span><span style="COLOR: #008080">&nbsp;8</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800080">__init__</span><span style="COLOR: #000000">(self,&nbsp;threadname,&nbsp;filename):<br></span><span style="COLOR: #008080">&nbsp;9</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self._file&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;filename<br></span><span style="COLOR: #008080">10</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;threading.Thread.</span><span style="COLOR: #800080">__init__</span><span style="COLOR: #000000">(self,&nbsp;name&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;threadname)<br></span><span style="COLOR: #008080">11</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">12</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">def</span><span style="COLOR: #000000">&nbsp;run(self):<br></span><span style="COLOR: #008080">13</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">global</span><span style="COLOR: #000000">&nbsp;DICTHOSTS<br></span><span style="COLOR: #008080">14</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">try</span><span style="COLOR: #000000">:<br></span><span style="COLOR: #008080">15</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_fhandle&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;open(self._file,&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">r</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">)<br></span><span style="COLOR: #008080">16</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;line&nbsp;</span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000">&nbsp;_fhandle:<br></span><span style="COLOR: #008080">17</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">try</span><span style="COLOR: #000000">:<br></span><span style="COLOR: #008080">18</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;host&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;urlparse.urlsplit(line.split(</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">","</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">)[</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">])[</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">]<br></span><span style="COLOR: #008080">19</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">except</span><span style="COLOR: #000000">&nbsp;IndexError:<br></span><span style="COLOR: #008080">20</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">pass</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">21</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">22</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;host:<br></span><span style="COLOR: #008080">23</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;DICTHOSTS.has_key(host):<br></span><span style="COLOR: #008080">24</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DICTHOSTS[host]&nbsp;</span><span style="COLOR: #000000">+=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">25</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">else</span><span style="COLOR: #000000">:<br></span><span style="COLOR: #008080">26</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DICTHOSTS[host]&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">27</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">finally</span><span style="COLOR: #000000">:<br></span><span style="COLOR: #008080">28</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_fhandle.close()<br></span><span style="COLOR: #008080">29</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">30</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">print</span><span style="COLOR: #000000">&nbsp;self.getName(),&nbsp;self._file,&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">has&nbsp;been&nbsp;traversed.</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">DICTHOSTS&nbsp;has</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">,&nbsp;len(DICTHOSTS),&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">items.</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">31</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">32</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">if</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800080">__name__</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">==</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">__main__</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">:<br></span><span style="COLOR: #008080">33</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;sortedList&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;[]<br></span><span style="COLOR: #008080">34</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;path&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">E:/workspace/URLsSorter/src/titleurl/</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000"><br></span><span style="COLOR: #008080">35</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;i&nbsp;</span><span style="COLOR: #0000ff">in</span><span style="COLOR: #000000">&nbsp;range(</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #000000">21</span><span style="COLOR: #000000">):<br></span><span style="COLOR: #008080">36</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;si&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;str(i)<br></span><span style="COLOR: #008080">37</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reader&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;CSVReader(</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">Thread</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;si,&nbsp;path&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">titleurl</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;si&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">.csv</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">)<br></span><span style="COLOR: #008080">38</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reader.start()<br></span><span style="COLOR: #008080">39</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reader.join()<br></span><span style="COLOR: #008080">40</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top><br></span><span style="COLOR: #008080">41</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">42</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;sortedList&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;sorted(DICTHOSTS.items(),&nbsp;key&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;itemgetter(</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">),&nbsp;reverse&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;True)<br></span><span style="COLOR: #008080">43</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;<br></span><span style="COLOR: #008080">44</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;writter&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;csv.writer(open(path&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">Result.csv</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">,&nbsp;</span><span style="COLOR: #800000">'</span><span style="COLOR: #800000">wb</span><span style="COLOR: #800000">'</span><span style="COLOR: #000000">))<br></span><span style="COLOR: #008080">45</span><span style="COLOR: #000000"><img src="http://www.cnitblog.com/Images/OutliningIndicators/None.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;writter.writerows(sortedList)</span></span></div>
<img src ="http://www.cnitblog.com/donne/aggbug/37258.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cnitblog.com/donne/" target="_blank">Don Li</a> 2007-12-03 09:44 <a href="http://www.cnitblog.com/donne/archive/2007/12/03/37258.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>