﻿<?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>博客园-让生活Web个够</title><link>http://www.cnblogs.com/fengmk2/</link><description>今天你Web了吗？</description><language>zh-cn</language><lastBuildDate>Sat, 11 Oct 2008 08:51:56 GMT</lastBuildDate><pubDate>Sat, 11 Oct 2008 08:51:56 GMT</pubDate><ttl>60</ttl><item><title>Python tips: 超时装饰器, @timeout decorator</title><link>http://www.cnblogs.com/fengmk2/archive/2008/08/30/python_tips_timeout_decorator.html</link><dc:creator>MK2</dc:creator><author>MK2</author><pubDate>Sat, 30 Aug 2008 14:29:00 GMT</pubDate><guid>http://www.cnblogs.com/fengmk2/archive/2008/08/30/python_tips_timeout_decorator.html</guid><wfw:comment>http://www.cnblogs.com/fengmk2/comments/1280338.html</wfw:comment><comments>http://www.cnblogs.com/fengmk2/archive/2008/08/30/python_tips_timeout_decorator.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.cnblogs.com/fengmk2/comments/commentRss/1280338.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/fengmk2/services/trackbacks/1280338.html</trackback:ping><description><![CDATA[<p>最近工作有点多，趁周末有空，继续分享我在学习和使用python过程中的一些小tips。 <br />
</p>
<p>有没有遇到过这样的事情：对数据库执行插入或更新操作，因为数据量大或其他原因，导致此次操作非常耗时，有时甚至等上好几个小时，也无法完成。很郁闷，怎么操作不超时啊？因为数据库配置时超时时间很长，并且有些操作又是需要很长时间的，所以不能修改默认的超时时间。</p>
<p>因为客观条件不允许，我们不能靠数据库超时来终止此次操作，所以必须要在自己的方法逻辑模块里实现超时检测的功能。<br />
</p>
<p>在python里有没有可以不用修改原来的方法内部逻辑，就能实现超时检测呢？肯定有啦，就是利用装饰器。装饰器是什么？在博客园找到了一篇介绍文章：<a target="_blank" href="http://www.cnblogs.com/Jifangliang/archive/2008/07/22/1248313.html">函数和方法装饰漫谈(Function decorator)</a>。</p>
<p>废话听完，我现在介绍主角出场：超时装饰器，timeout decorator。</p>
<p>超时检测逻辑：启动新子线程执行指定的方法，主线程等待子线程的运行结果，若在指定时间内子线程还未执行完毕，则判断为超时，抛出超时异常，并杀掉子线程；否则未超时，返回子线程所执行的方法的返回值。<br />
</p>
<p>在实现过程中，发现python默认模块里是没有方法可以杀掉线程的，怎么办呢？当然先问问google或百度，果然，keill thread这个关键词很热门，很快就搜索到我想要的东西了:"<a title="Kill a thread in Python" target="_blank" href="http://mail.python.org/pipermail/python-list/2004-May/260937.html">Kill a thread in Python</a>"，就是以下这个KThread类，它继承了threading.Thread，并添加了kill方法，让我们能杀掉它：<br />
</p>
<p>&nbsp;<br />
</p>
<div class="cnblogs_code"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">import</span><span style="color: #000000;">&nbsp;sys<br />
<br />
<br />
</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;KThread(threading.Thread):<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #800000;">"""</span><span style="color: #800000;">A&nbsp;subclass&nbsp;of&nbsp;threading.Thread,&nbsp;with&nbsp;a&nbsp;kill()<br />
&nbsp;&nbsp;&nbsp;&nbsp;method.<br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;Come&nbsp;from:<br />
&nbsp;&nbsp;&nbsp;&nbsp;Kill&nbsp;a&nbsp;thread&nbsp;in&nbsp;Python:&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;http://mail.python.org/pipermail/python-list/2004-May/260937.html<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #800000;">"""</span><span style="color: #000000;"><br />
&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;</span><span style="color: #000000;">*</span><span style="color: #000000;">args,&nbsp;</span><span style="color: #000000;">**</span><span style="color: #000000;">kwargs):<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;threading.Thread.</span><span style="color: #800080;">__init__</span><span style="color: #000000;">(self,&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">args,&nbsp;</span><span style="color: #000000;">**</span><span style="color: #000000;">kwargs)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.killed&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;False<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">def</span><span style="color: #000000;">&nbsp;start(self):<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #800000;">"""</span><span style="color: #800000;">Start&nbsp;the&nbsp;thread.</span><span style="color: #800000;">"""</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.</span><span style="color: #800080;">__run_backup</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;self.run<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.run&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;self.</span><span style="color: #800080;">__run</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">#</span><span style="color: #008000;">&nbsp;Force&nbsp;the&nbsp;Thread&nbsp;to&nbsp;install&nbsp;our&nbsp;trace.</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;threading.Thread.start(self)<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">def</span><span style="color: #000000;">&nbsp;</span><span style="color: #800080;">__run</span><span style="color: #000000;">(self):<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #800000;">"""</span><span style="color: #800000;">Hacked&nbsp;run&nbsp;function,&nbsp;which&nbsp;installs&nbsp;the<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;trace.</span><span style="color: #800000;">"""</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sys.settrace(self.globaltrace)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.</span><span style="color: #800080;">__run_backup</span><span style="color: #000000;">()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.run&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;self.</span><span style="color: #800080;">__run_backup</span><span style="color: #000000;"><br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">def</span><span style="color: #000000;">&nbsp;globaltrace(self,&nbsp;frame,&nbsp;why,&nbsp;arg):<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;why&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;</span><span style="color: #800000;">'</span><span style="color: #800000;">call</span><span style="color: #800000;">'</span><span style="color: #000000;">:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;self.localtrace<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;">:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;None<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">def</span><span style="color: #000000;">&nbsp;localtrace(self,&nbsp;frame,&nbsp;why,&nbsp;arg):<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;self.killed:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;why&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;</span><span style="color: #800000;">'</span><span style="color: #800000;">line</span><span style="color: #800000;">'</span><span style="color: #000000;">:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">raise</span><span style="color: #000000;">&nbsp;SystemExit()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;self.localtrace<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">def</span><span style="color: #000000;">&nbsp;kill(self):<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;self.killed&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;True</span></div>
<p><br />
</p>
<p>好了，万事戒备，让我们来完成剩下的代码吧，也就是timeout decorator：</p>
<div class="cnblogs_code"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;Timeout(Exception):<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #800000;">"""</span><span style="color: #800000;">function&nbsp;run&nbsp;timeout</span><span style="color: #800000;">"""</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;<br />
</span><span style="color: #0000ff;">def</span><span style="color: #000000;">&nbsp;timeout(seconds):<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #800000;">"""</span><span style="color: #800000;">超时装饰器，指定超时时间<br />
&nbsp;&nbsp;&nbsp;&nbsp;若被装饰的方法在指定的时间内未返回，则抛出Timeout异常</span><span style="color: #800000;">"""</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">def</span><span style="color: #000000;">&nbsp;timeout_decorator(func):<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #800000;">"""</span><span style="color: #800000;">真正的装饰器</span><span style="color: #800000;">"""</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">def</span><span style="color: #000000;">&nbsp;_new_func(oldfunc,&nbsp;result,&nbsp;oldfunc_args,&nbsp;oldfunc_kwargs):<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result.append(oldfunc(</span><span style="color: #000000;">*</span><span style="color: #000000;">oldfunc_args,&nbsp;</span><span style="color: #000000;">**</span><span style="color: #000000;">oldfunc_kwargs))<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">def</span><span style="color: #000000;">&nbsp;_(</span><span style="color: #000000;">*</span><span style="color: #000000;">args,&nbsp;</span><span style="color: #000000;">**</span><span style="color: #000000;">kwargs):<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;result&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;[]<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;new_kwargs&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;{&nbsp;</span><span style="color: #008000;">#</span><span style="color: #008000;">&nbsp;create&nbsp;new&nbsp;args&nbsp;for&nbsp;_new_func,&nbsp;because&nbsp;we&nbsp;want&nbsp;to&nbsp;get&nbsp;the&nbsp;func&nbsp;return&nbsp;val&nbsp;to&nbsp;result&nbsp;list</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&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;">oldfunc</span><span style="color: #800000;">'</span><span style="color: #000000;">:&nbsp;func,<br />
&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;">result</span><span style="color: #800000;">'</span><span style="color: #000000;">:&nbsp;result,<br />
&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;">oldfunc_args</span><span style="color: #800000;">'</span><span style="color: #000000;">:&nbsp;args,<br />
&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;">oldfunc_kwargs</span><span style="color: #800000;">'</span><span style="color: #000000;">:&nbsp;kwargs<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;thd&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;KThread(target</span><span style="color: #000000;">=</span><span style="color: #000000;">_new_func,&nbsp;args</span><span style="color: #000000;">=</span><span style="color: #000000;">(),&nbsp;kwargs</span><span style="color: #000000;">=</span><span style="color: #000000;">new_kwargs)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;thd.start()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;thd.join(seconds)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;alive&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;thd.isAlive()<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;thd.kill()&nbsp;</span><span style="color: #008000;">#</span><span style="color: #008000;">&nbsp;kill&nbsp;the&nbsp;child&nbsp;thread</span><span style="color: #008000;"><br />
</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;alive:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">raise</span><span style="color: #000000;">&nbsp;Timeout(u</span><span style="color: #800000;">'</span><span style="color: #800000;">function&nbsp;run&nbsp;too&nbsp;long,&nbsp;timeout&nbsp;%d&nbsp;seconds.</span><span style="color: #800000;">'</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">%</span><span style="color: #000000;">&nbsp;seconds)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;">:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;result[0]<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_.</span><span style="color: #800080;">__name__</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;func.</span><span style="color: #800080;">__name__</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;_.</span><span style="color: #800080;">__doc__</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;func.</span><span style="color: #800080;">__doc__</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;_<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;timeout_decorator</span></div>
<p>&nbsp;</p>
<p>真的能运行吗？写个测试程序运行运行：<br />
</p>
<div class="cnblogs_code"><!--<br />
<br />
Code highlighting produced by Actipro CodeHighlighter (freeware)<br />
http://www.CodeHighlighter.com/<br />
<br />
--><span style="color: #000000;">@timeout(</span><span style="color: #000000;">5</span><span style="color: #000000;">)<br />
</span><span style="color: #0000ff;">def</span><span style="color: #000000;">&nbsp;method_timeout(seconds,&nbsp;text):<br />
&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;">start</span><span style="color: #800000;">'</span><span style="color: #000000;">,&nbsp;seconds,&nbsp;text<br />
&nbsp;&nbsp;&nbsp;&nbsp;time.sleep(seconds)<br />
&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;">finish</span><span style="color: #800000;">'</span><span style="color: #000000;">,&nbsp;seconds,&nbsp;text<br />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;seconds<br />
<br />
</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 />
&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">for</span><span style="color: #000000;">&nbsp;sec&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;">10</span><span style="color: #000000;">):<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">try</span><span style="color: #000000;">:<br />
&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;">*</span><span style="color: #800000;">'</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">20</span><span style="color: #000000;"><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">print</span><span style="color: #000000;">&nbsp;method_timeout(sec,&nbsp;</span><span style="color: #800000;">'</span><span style="color: #800000;">test&nbsp;waiting&nbsp;%d&nbsp;seconds</span><span style="color: #800000;">'</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">%</span><span style="color: #000000;">&nbsp;sec)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">except</span><span style="color: #000000;">&nbsp;Timeout,&nbsp;e:<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">print</span><span style="color: #000000;">&nbsp;e</span></div>
<p>&nbsp;</p>
<p>看，真的行：</p>
<p>&nbsp;<img alt="" src="http://www.cnblogs.com/images/cnblogs_com/fengmk2/timeout_decorator.jpg" height="491" width="359" /></p>
<p>&nbsp;</p>
<p>本次的tips可能有点复杂，运用到多线程，装饰器等，希望它对你有所帮助。<br />
</p>
<p>PS：山顶风光果然一流，独缺美女相伴!!!<img src="http://www.cnblogs.com/Emoticons/yoyocici/223853735.gif"  alt="" /> </p>
<p><img src="file:///C:/DOCUME%7E1/ADMINI%7E1/LOCALS%7E1/Temp/moz-screenshot.jpg" alt="" /> </p><img src ="http://www.cnblogs.com/fengmk2/aggbug/1280338.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42938/" target="_blank">[新闻]11个处于悬崖边缘的 Web 公司</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>Python tips: 让Unicode变简单</title><link>http://www.cnblogs.com/fengmk2/archive/2008/08/01/1257771.html</link><dc:creator>MK2</dc:creator><author>MK2</author><pubDate>Thu, 31 Jul 2008 17:15:00 GMT</pubDate><guid>http://www.cnblogs.com/fengmk2/archive/2008/08/01/1257771.html</guid><wfw:comment>http://www.cnblogs.com/fengmk2/comments/1257771.html</wfw:comment><comments>http://www.cnblogs.com/fengmk2/archive/2008/08/01/1257771.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/fengmk2/comments/commentRss/1257771.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/fengmk2/services/trackbacks/1257771.html</trackback:ping><description><![CDATA[对于我这个从.NET过来的人，对python的str和unicode会感到非常不适应。经常在一些常用的地方遇到编码异常问题。如保存字符串到文本中，是要先编码还是直接保存呢？字符串是str还是unicode呢？保存字符串到数据库是直接保存str又或是先将unicode编码得到的str呢？<br />好多个问号，这都是我个python初学者碰到的问题。在尝试多次痛苦后，总算有了一些思路。原来unicode早已在python实现的很好，只是我使用不当罢了。<br /><br /><b>一个很关键的并且要常记住的，就是代码中所有字符串都统一使用unicode，而不是str。</b>这样，自己就能很清楚要处理的字符串类型了。请记住，是所有，任何地方。<br />例如：<br />&gt;&gt;&gt; s1 = u'%s欢迎您!' % u'北京'<br />&gt;&gt;&gt; s1<br />u'\u5317\u4eac\u6b22\u8fce\u60a8\uff01'<br />&gt;&gt;&gt; print s1<br />北京欢迎你!<br /><br />若像这样，就会抛异常：<br />&gt;&gt;&gt; s2 = '%s欢迎您!' % u'北京'<br />Traceback (most recent call last):<br />  File "&lt;stdin&gt;", line 1, in &lt;module&gt;<br />UnicodeDecodeError: 'ascii' codec can't decode byte 0xe6 in position 2: ordinal not in range(128)<br />由UnicodeDecodeError可猜想得到，解析器尝试使用ascii对'%s欢迎您!'进行解码，由于'%s欢迎您!'实际是使用utf-8编码的（这是我系统终端默认的），所以使用ascii解码肯定会错，只要如下，就可以重现这个异常了：<br />&gt;&gt;&gt; s2 = '%s欢迎您!'.decode('ascii')<br />Traceback (most recent call last):<br />  File "&lt;stdin&gt;", line 1, in &lt;module&gt;<br />UnicodeDecodeError: 'ascii' codec can't decode byte 0xe6 in position 2: ordinal not in range(128)<br /><b><br />分清encode和decode。str --&gt; decode(c) --&gt; unicode,   unicode --&gt; encode(c) --&gt; str，其中编码类型c必须相同。<br /><br />将unicode字符串写入文件前先使用特定编码对其进行编码(如unicodestr.encode('utf-8'))得到str，保证写入文件的是str；从文件读取到str，然后对其进行解码(如encodestr.decode('utf-8'))得到unicode。</b>这是互逆的两个操作，编码类型一定要一致，否则会出现异常。<b><br /></b><br />自己支持了unicode，但是你团队的其他人是否都使用unicode呢？你使用的其他模块是否也使用unicode呢？这个一定要清楚的，不然同样会出现许多因为编码问题的异常。<b><br /><br /></b>好了，晚了，随便写了点，大家晚安，2008.8.1，本世纪的第一次日全蚀，你要看吗？<b><br /><br /></b>Technorati 标签: <a class="performancingtags" href="http://technorati.com/tag/python" rel="tag">python</a>, <a class="performancingtags" href="http://technorati.com/tag/unicode" rel="tag">unicode</a>, <a class="performancingtags" href="http://technorati.com/tag/str" rel="tag">str</a><img src ="http://www.cnblogs.com/fengmk2/aggbug/1257771.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42937/" target="_blank">[新闻]扎克博格：Facebook要先赚吆喝后赚钱</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>PE文件格式小炒</title><link>http://www.cnblogs.com/fengmk2/archive/2008/06/23/1228393.html</link><dc:creator>MK2</dc:creator><author>MK2</author><pubDate>Mon, 23 Jun 2008 11:32:00 GMT</pubDate><guid>http://www.cnblogs.com/fengmk2/archive/2008/06/23/1228393.html</guid><wfw:comment>http://www.cnblogs.com/fengmk2/comments/1228393.html</wfw:comment><comments>http://www.cnblogs.com/fengmk2/archive/2008/06/23/1228393.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/fengmk2/comments/commentRss/1228393.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/fengmk2/services/trackbacks/1228393.html</trackback:ping><description><![CDATA[<p>最近都在研究如何利用最少的字节判断两个PE文件是否相同。</p>
<p>PE文件几个关键：</p>
<p>1. 在一个PE文件的开始处，我们会看到一个MS-DOS可执行体（英语叫&#8220;stub&#8221;,意为&#8220;根，存根&#8221;）；它使任何PE文件都是一个有效的MS-DOS可执行文件。如图蓝色框部分。0x5A4D：MZ，每个PE文件都是以此开始。</p>
<p><a href="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/PE_8E98/image_2.png"><img style="border: 0px none ;" alt="image" src="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/PE_8E98/image_thumb.png" border="0" height="440" width="292" /></a> </p>
<p>&nbsp;</p>
<p>2. 在DOS-根之后是一个32位的签名以及魔数0x00004550 (IMAGE_NT_SIGNATURE)（意为&#8220;NT签名&#8221;，也就是PE签名；十六进制数45和50分别代表ASCII码字母E和P）。</p>
<p><a href="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/PE_8E98/image_4.png"><img style="border: 0px none ;" alt="image" src="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/PE_8E98/image_thumb_1.png" border="0" height="61" width="251" /></a> </p>
<p>3. </p>
<p><a href="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/PE_8E98/image_6.png"><img style="border: 0px none ;" alt="image" src="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/PE_8E98/image_thumb_2.png" border="0" height="571" width="228" /></a> </p>
<p>&nbsp;</p>
<p>4. DOS-根和签名（DOS-stub and Signature）</p>
<p><a href="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/PE_8E98/image_10.png"><img style="border: 0px none ;" alt="image" src="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/PE_8E98/image_thumb_4.png" border="0" height="453" width="635" /></a> </p>
<p>你可以通过确认DOS-头部分是否为一个IMAGE_DOS_HEADER（DOS头）结构来认出DOS-根，它的前两个字节必须为连续的两个字母&#8220;MZ&#8221;（有一个#define IMAGE_DOS_SIGNATURE的定义是针对这个WORD单元的）。</p>
<p>DOS-根的概念很早从16位windows的可执行文件（当时是&#8220;NE&#8221;格式），现在是PE。</p>
<p>可以通过跟在后面的签名来将一个PE二进制文件和其它含有根的二进制文件区分开来，跟在后面的签名可由头成员'e_lfanew'（它是从字节偏移地址 60(0x3C)处开始的，有32字节长）所设定的偏移地址找到。对于OS/2系统和Windows系统的二进制文件来说，签名是一个16位的word单元；对于PE 文件来说，它是一个按照8位字节边界对齐的32位的longword单元，并且IMAGE_NT_SIGNATURE（NT签名）的值已由#defined定义为0x00004550（即字母&#8220;PE/0/0&#8221;）。</p>
<p>即：判断一个文件是否PE：1）判断开始两字节是否 0x5A4D；2）根据0x3C~3F的得到偏移地址，然后根据偏移地址获得签名，判断该签名是否属于PE即可。</p>
<p>&nbsp;</p>
<p>5. 文件头</p>
<p><a href="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/PE_8E98/image_14.png"><img style="border: 0px none ;" alt="image" src="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/PE_8E98/image_thumb_6.png" border="0" height="46" width="246" /></a>&nbsp; </p>
<p>开始于0x00E4，有0x14字节长，到0xF8：   <br />
&nbsp;&nbsp;&nbsp; Machine&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; 4c 01&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; i386    <br />
&nbsp;&nbsp;&nbsp; NumberOfSections&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 03 00&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; 代码段和数据段    <br />
&nbsp;&nbsp;&nbsp; TimeDateStamp&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 20 84 7D 3B ;&nbsp; <br />
&nbsp;&nbsp;&nbsp; PointerToSymbolTable&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 00 00 00 00 ; 未用    <br />
&nbsp;&nbsp;&nbsp; NumberOfSymbols&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 00 00 00 00 ; 未用    <br />
&nbsp;&nbsp;&nbsp; SizeOfOptionalHeader&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; e0 00&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; 常量    <br />
&nbsp;&nbsp;&nbsp; Characteristics&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0F 01(00<font color="#ff0000">0</font>0 000<font color="#ff0000">1</font> 0000 11<font color="#ff0000"><strong>1</strong>1</font>B)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; 32位机器上的可执行文件</p>
<p>&nbsp;</p>
<p>成员&#8220;Characteristics（特性）&#8221;是一个16位的，由许多标志位形成的集合组成，但大多数标志位只对目标文件和库文件有效。具体如下：   <br />
&nbsp;&nbsp;&nbsp; 位0 IMAGE_FILE_RELOCS_STRIPPED（重定位被剥离文件） 表示如果文件中没有重定位信息，该位置1，这就表明各节的重定位信息都在它们各自的节中；可执行文件不使用该位，它们的重定位信息放在下面将要描述的&#8220;base relocation&#8221;（基址重定位）目录中。    <br />
&nbsp;&nbsp;&nbsp; 位1 IMAGE_FILE_EXECUTABLE_IMAGE（可执行映象文件） 表示如果文件是一个可执行文件，也即不是目标文件或者库文件时，置1。如果链接器尝试创建一个可执行文件，却因为一些原因失败了，并保存映像以便下次例如增量链接时使用，此时此标志位也可能置1。    <br />
&nbsp;&nbsp;&nbsp; 位2 IMAGE_FILE_LINE_NUMS_STRIPPED（行数被剥离文件） 表示如果行数信息被剥除，此位置1；此位也不用于可执行文件。    <br />
&nbsp;&nbsp;&nbsp; 位3 IMAGE_FILE_LOCAL_SYMS_STRIPPED（本地符号被剥离文件） 表示如果文件中没有关于本地符号的信息时，此位置1（此位也不用于可执行文件）。    <br />
&nbsp;&nbsp;&nbsp; 位4 IMAGE_FILE_AGGRESIVE_WS_TRIM（强行工作集修剪文件） 表示如果操作系统被假定为：通过将正在运行的进程（它所使用的内存数量）强行的页清除来修剪它的工作集时，此位置1。如果一进程是大部分时间处于等待，且一天中仅被唤醒一次的演示性的应用程序之类时，此位也应该被置1。    <br />
&nbsp;&nbsp;&nbsp; 位7 IMAGE_FILE_BYTES_REVERSED_LO（低字节变换文件）和 位 15IMAGE_FILE_BYTES_REVERSED_HI（高字节变换文件） 表示如果一文件的字节序不是机器所预期的形式，因此它在读入前必须调换字节时，此位置1。这样做对可执行文件是不可靠的（操作系统期望可执行文件都已经被正确地按字节排整齐了）。    <br />
&nbsp;&nbsp;&nbsp; 位8 IMAGE_FILE_32BIT_MACHINE（32位机器文件） 表示如果使用的机器被期望为32位的机器时，此位置1。现在的应用程序总将此位置1；NT5系统可能工作不同。    <br />
&nbsp;&nbsp;&nbsp; 位9 IMAGE_FILE_DEBUG_STRIPPED（调试信息被剥离文件) 表示如果文件中没有调试信息，此位置1。此位可执行文件不用。按照其它信息([6])（这里指的是参考书目中的第[6]种----译者注），此位被称作&#8220;恒定&#8221;，并且当一个映象文件只有在被装入优先的装入地址才能运行（亦即：此文件不可重定位）时，此位置1。    <br />
&nbsp;&nbsp;&nbsp; 位10 IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP（移动介质文件从交换文件运行) 表示如果一个应用程序不可以从可移动的介质，如软盘或CD-ROM上运行时，此位置1。在这种情况下，建议操作系统将文件复制到交换文件并从那里执行。    <br />
&nbsp;&nbsp;&nbsp; 位11 IMAGE_FILE_NET_RUN_FROM_SWAP（网络文件从交换文件运行) 表示如果一个应用程序不可以从网络上运行时，此位置1。在这种情况下，建议操作系统将文件复制到交换文件并从那里执行。    <br />
&nbsp;&nbsp;&nbsp; 位12 IMAGE_FILE_SYSTEM（系统文件) 表示如果文件是一个象驱动程序那样的系统文件，此位置1。此位可执行文件不用；我所见过的所有NT系统的驱动程序也不用。    <br />
&nbsp;&nbsp;&nbsp; 位13 IMAGE_FILE_DLL（DLL文件) 表示如果文件是一个DLL文件时，此位置1。    <br />
&nbsp;&nbsp;&nbsp; 位14 IMAGE_FILE_UP_SYSTEM_ONLY（仅但处理器系统的文件) 表示如果文件不设计运行在多处理器系统上（也就是说，因为此文件严格地依赖单一处理器的一些方式工作，所以它会发生冲突）时，此位置1。</p>
<p>在看来一个DLL的文件头</p>
<p><a href="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/PE_8E98/image_16.png"><img style="border: 0px none ;" alt="image" src="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/PE_8E98/image_thumb_7.png" border="0" height="79" width="265" /></a> </p>
<p>Characteristics&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0E 21(00<font color="#ff0000">1</font>0 000<font color="#ff0000">1</font> 0000 11<font color="#ff0000">10</font>B 高-低)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ; 32位机器上的DLL文件</p>
<p>&nbsp;</p>
<p>参考：</p>
<p><a title="http://bbs.pediy.com/showthread.php?threadid=21932" href="http://bbs.pediy.com/showthread.php?threadid=21932">http://bbs.pediy.com/showthread.php?threadid=21932</a></p>
<img src ="http://www.cnblogs.com/fengmk2/aggbug/1228393.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42936/" target="_blank">[新闻]金融风暴改写富豪榜排名　巴菲特资产超盖茨</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>测试scribefire</title><link>http://www.cnblogs.com/fengmk2/archive/2008/06/10/1216910.html</link><dc:creator>MK2</dc:creator><author>MK2</author><pubDate>Tue, 10 Jun 2008 11:23:00 GMT</pubDate><guid>http://www.cnblogs.com/fengmk2/archive/2008/06/10/1216910.html</guid><wfw:comment>http://www.cnblogs.com/fengmk2/comments/1216910.html</wfw:comment><comments>http://www.cnblogs.com/fengmk2/archive/2008/06/10/1216910.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/fengmk2/comments/commentRss/1216910.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/fengmk2/services/trackbacks/1216910.html</trackback:ping><description><![CDATA[A呵呵，一直都是用WLW写blog的，很久之前就装了<a target="_blank" href="http://www.scribefire.com/help/getting-started/">Scribefire，</a>一直都没用，今天来个测试，呵呵，如果满意，以后就用它了。<br /><br /><br /><br />直接帖截图测试：<br /><br /><img src="http://www.cnblogs.com/images/cnblogs_com/fengmk2/moz-screenshot-1.jpg" alt="" /> <br /><br />edit<br /><br /><img src="http://www.cnblogs.com/images/cnblogs_com/fengmk2/moz-screenshot-2.jpg" alt="" /><br /><br /><br /><br />上传图片测试：OK<br /><br /><img style="max-width: 800px;" src="http://www.cnblogs.com/images/cnblogs_com/fengmk2/wing3.jpg" /><br /><br /><br /><br /><strong>测试其他吧</strong>，<em>哈哈</em>，<strike><em><u><strong>乱来。<br /><br />©®°±¶º¿¿¾<br /><br /><br />呵呵，看来真的可以取代WLW<br /><br /><br /><br /></strong></u></em></strike>Technorati Tags: <a class="performancingtags" href="http://technorati.com/tag/scribefire" rel="tag">scribefire</a>, <a class="performancingtags" href="http://technorati.com/tag/firefox" rel="tag">firefox</a>, <a class="performancingtags" href="http://technorati.com/tag/wlw" rel="tag">wlw</a><img src ="http://www.cnblogs.com/fengmk2/aggbug/1216910.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42935/" target="_blank">[新闻]红杉资本发出严重警告：黄金时代已成历史</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>Firefox插件备忘录</title><link>http://www.cnblogs.com/fengmk2/archive/2008/06/09/1216159.html</link><dc:creator>MK2</dc:creator><author>MK2</author><pubDate>Mon, 09 Jun 2008 02:49:00 GMT</pubDate><guid>http://www.cnblogs.com/fengmk2/archive/2008/06/09/1216159.html</guid><wfw:comment>http://www.cnblogs.com/fengmk2/comments/1216159.html</wfw:comment><comments>http://www.cnblogs.com/fengmk2/archive/2008/06/09/1216159.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cnblogs.com/fengmk2/comments/commentRss/1216159.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/fengmk2/services/trackbacks/1216159.html</trackback:ping><description><![CDATA[<p>因经常在多台机器上使用Firefox，难免会想装一些已经习惯了的插件（晕，都依赖他们），没安装上总是用起来不顺手。于是就有了这篇文章。</p>  <p>1. 第一个要备忘的肯定是它：<a href="http://www.google.com/tools/firefox/browsersync/" target="_blank">Google Browser Sync</a></p>  <p><a href="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/Firefox_84EA/image_2.png"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="100" alt="image" src="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/Firefox_84EA/image_thumb.png" width="744" border="0" /></a> </p>  <p>可以同步些什么？看看这个截图吧：</p>  <p><a href="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/Firefox_84EA/image_4.png"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="389" alt="image" src="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/Firefox_84EA/image_thumb_1.png" width="417" border="0" /></a> </p>  <p>很Cool吧，仿佛在那台机打开FF，都感觉是一样的，完全获取回上次的所有状态，并且支持加密传输，这样个人私隐就不会泄露了。</p>  <p>2. <a href="https://addons.mozilla.org/en-US/firefox/addon/2888" target="_blank">GMarks</a></p>  <p>虽然说<a href="http://www.google.com/tools/firefox/browsersync/" target="_blank">Google Browser Sync</a>可以同步Bookmarks，但是我还是喜欢将Bookmarks保存到互联网上，<a href="https://addons.mozilla.org/en-US/firefox/addon/2888" target="_blank">GMarks</a>就是一个<a href="http://google.com/bookmarks" target="_blank">Google Bookmarks</a>的插件，使用也非常简单，Bookmarks太多了吧，不記得放在那个位置了吧，呵呵，不怕，在自己的Bookmarks上搜索一下不就行了？</p>  <p><a href="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/Firefox_84EA/image_6.png"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="174" alt="image" src="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/Firefox_84EA/image_thumb_2.png" width="644" border="0" /></a> </p>  <p>3. <a href="http://pagesperso-orange.fr/marc.boullet/index.html" target="_blank">All-in-One Gestures Extension</a></p>  <p>有使用鼠标手势控制的习惯吧？怕使用了Firefox而无法拥有这个功能吗？呵呵，哪<a href="http://pagesperso-orange.fr/marc.boullet/index.html" target="_blank">All-in-One Gestures Extension</a>肯定是你的最爱，完全支持你想要的手势。</p>  <p><a href="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/Firefox_84EA/image_8.png"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="484" alt="image" src="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/Firefox_84EA/image_thumb_3.png" width="538" border="0" /></a> </p>  <p><a href="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/Firefox_84EA/image_10.png"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="307" alt="image" src="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/Firefox_84EA/image_thumb_4.png" width="603" border="0" /></a> </p>  <p>4. <a href="https://addons.mozilla.org/en-US/firefox/addon/2082" target="_blank">DictCN</a> (呵呵，忘记推荐<a href="http://dict.hjenglish.com/" target="_blank">沪江小D</a>，绝对比这个精彩多了！！！)</p>  <p>呵呵，像我这些英语很差但是又要经常看英文的人，这个插件肯定比钱包更加重要，放在你的FF上吧，肯定会用上的，特别是它还支持发音功能。</p>  <p><a href="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/Firefox_84EA/image_12.png"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="104" alt="image" src="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/Firefox_84EA/image_thumb_5.png" width="318" border="0" /></a> <a href="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/Firefox_84EA/image_14.png"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="169" alt="image" src="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/Firefox_84EA/image_thumb_6.png" width="179" border="0" /></a> </p>  <p>5. <a href="http://www.krickelkrackel.de/autohide/" target="_blank">AutoHide</a></p>  <p>觉得FF上方的工具栏太占位置了吗？导致看到的页面太小了吧？呵呵，这个插件绝对帮你将工具栏完全隐藏了，按Shift+F11让FF全屏吧。</p>  <p><a href="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/Firefox_84EA/image_16.png"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="244" alt="image" src="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/Firefox_84EA/image_thumb_7.png" width="229" border="0" /></a> </p>  <p>6. <a href="http://www.getfirebug.com/" target="_blank">Firebug</a> 不顶不行</p>  <p>呵呵，这个不用我介绍了吧，太出名了！！！</p>  <p><a href="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/Firefox_84EA/image_20.png"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="446" alt="image" src="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/Firefox_84EA/image_thumb_9.png" width="739" border="0" /></a></p>  <p>估计每个做Web开发的人的FF上都会有它。o(&#8745;_&#8745;)o...</p>  <p>7. <a href="http://showcase.uworks.net/" target="_blank">Showcase</a></p>  <p>经常打开几十个tab而又不想关掉它们吗？是不是要找一个tab花了很多时间？使用<a href="http://showcase.uworks.net/" target="_blank">Showcase</a>可以让你马上找到你想找的tab，不信？看看截图吧：</p>  <p><a href="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/Firefox_84EA/image_22.png"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="320" alt="image" src="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/Firefox_84EA/image_thumb_10.png" width="644" border="0" /></a> </p>  <p>想用了吧？</p>  <p>8. <a href="http://ietab.mozdev.org/" target="_blank">IE Tab</a></p>  <p>不用IE不行啊，有时候真的没有了IE，很多事情就没法做了，于是有打开IE。很麻烦吧，如果你的系统是Windows，那么<a href="http://ietab.mozdev.org/" target="_blank">IE Tab</a>可以很方便地设置当前页面使用IE内核访问，还可以设置更多的规则，唉，我们的世界没了IE真不容易：</p>  <p><a href="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/Firefox_84EA/image_24.png"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="243" alt="image" src="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/Firefox_84EA/image_thumb_11.png" width="644" border="0" /></a> </p>  <p>9. <font color="#acb613"><a href="http://screenshot-program.com/fireshot/" target="_blank">Fireshot</a></font></p>  <p>一个页面太长了吧，是否有想将整个页面截图处理的需求呢？<font color="#acb613"><a href="http://screenshot-program.com/fireshot/" target="_blank">Fireshot</a></font>可以实现，并且还有上传，直接将截图的链接发给你的朋友吧，呵呵，这样介绍网站，也是一个不错的选择。</p>  <p><a href="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/Firefox_84EA/image_32.png"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="537" alt="image" src="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/Firefox_84EA/image_thumb_15.png" width="804" border="0" /></a> </p>  <p><a href="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/Firefox_84EA/image_28.png"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="306" alt="image" src="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/Firefox_84EA/image_thumb_13.png" width="469" border="0" /></a> </p>  <p>10. <a href="http://www.xuldev.org/tabscope/" target="_blank">Tab Scope</a></p>  <p>想预览一下tab里面是什么内容吗？看看它是不是已经加载完了？这个插件可以提高你的兴趣。</p>  <p><a href="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/Firefox_84EA/image_30.png"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="377" alt="image" src="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/Firefox_84EA/image_thumb_14.png" width="426" border="0" /></a> </p>  <p>11. <a href="https://addons.mozilla.org/en-US/firefox/addon/6912" target="_blank">QuickDrag</a> </p>  <p>可以直接拖拉页面上的链接，并在新tab中打开，不用点鼠标中键了，Cool啊！！</p>  <p>12. <a href="http://www.iosart.com/firefox/colorzilla/" target="_blank">ColorZilla</a></p>  <p>可以获取页面上任意部位的颜色。</p>  <p><a href="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/Firefox_84EA/image_38.png"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="107" alt="image" src="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/Firefox_84EA/image_thumb_18.png" width="313" border="0" /></a> </p>  <p>??. <a href="http://customsoftwareconsult.com/extensions/" target="_blank">FEBE</a></p>  <p>好了，装了这么多插件，有备份这些插件的插件吗？呵呵，你都想备份了吧？用<a href="http://customsoftwareconsult.com/extensions/" target="_blank">FEBE</a>吧，你想怎样备份都可以。</p>  <p><a href="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/Firefox_84EA/image_34.png"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="608" alt="image" src="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/Firefox_84EA/image_thumb_16.png" width="533" border="0" /></a> </p>  <p><a href="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/Firefox_84EA/image_36.png"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="397" alt="image" src="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/Firefox_84EA/image_thumb_17.png" width="533" border="0" /></a> </p>  <p>这里可以查看更多截图：<a title="http://customsoftwareconsult.com/extensions/febe/febe50/FEBE5.0.html" href="http://customsoftwareconsult.com/extensions/febe/febe50/FEBE5.0.html">http://customsoftwareconsult.com/extensions/febe/febe50/FEBE5.0.html</a></p>  <p>&#160;</p>  <p>呵呵，今天到此为止吧，以后用到更多好的插件我会继续补充的，:-)</p>  <p>&#160;</p>  <p>希望对你有用！！</p>  <p>&#160;</p>  <div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:2bf0aa6c-de80-4707-9e8a-0ffdbb32586f" style="padding-right: 0px; display: inline; padding-left: 0px; float: none; padding-bottom: 0px; margin: 0px; padding-top: 0px">Technorati 标签: <a href="http://technorati.com/tags/Firefox" rel="tag">Firefox</a>,<a href="http://technorati.com/tags/Javascript" rel="tag">Javascript</a>,<a href="http://technorati.com/tags/Firebug" rel="tag">Firebug</a>,<a href="http://technorati.com/tags/IE" rel="tag">IE</a></div><img src ="http://www.cnblogs.com/fengmk2/aggbug/1216159.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42934/" target="_blank">[新闻]2008年10月11日科技博客精选</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>当AjaxForm遇上TinyMCE</title><link>http://www.cnblogs.com/fengmk2/archive/2008/06/08/1216013.html</link><dc:creator>MK2</dc:creator><author>MK2</author><pubDate>Sun, 08 Jun 2008 12:38:00 GMT</pubDate><guid>http://www.cnblogs.com/fengmk2/archive/2008/06/08/1216013.html</guid><wfw:comment>http://www.cnblogs.com/fengmk2/comments/1216013.html</wfw:comment><comments>http://www.cnblogs.com/fengmk2/archive/2008/06/08/1216013.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cnblogs.com/fengmk2/comments/commentRss/1216013.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/fengmk2/services/trackbacks/1216013.html</trackback:ping><description><![CDATA[<p>在没有使用<a href="http://www.malsup.com/jquery/form" target="_blank">AjaxForm</a>前，我做的一个小小的评论提交的Web form，评论内容使用了<a href="http://tinymce.moxiecode.com" target="_blank">TinyMCE</a>做文本编辑。为了增加一点点的用户体验，就顺手拿<a href="http://www.malsup.com/jquery/form" target="_blank">AjaxForm</a>来实现Ajax提交。可是发现出现了一个意外的事情。就是每次提交，第一次提交时，<a href="http://www.malsup.com/jquery/form" target="_blank">AjaxForm</a>会无法获得当前编辑的评论内容，即TextArea里面的内容，要再点击一次提交，才能将TextArea的内容提交上去。</p> <p>关键是TinyMCE上的内容没有在提交前更新到TextArea中。于是想看看<a href="http://www.malsup.com/jquery/form" target="_blank">AjaxForm</a>是否有在提交前的事件绑定，发现在beforeSubmit事件中，formData的内容已经被填充，虽然可以在此处自行将当前的<a href="http://tinymce.moxiecode.com" target="_blank">TinyMCE</a>的内容填充上去(<a href="http://ray.imiddle.net/2008/01/17/ajaxform-and-tinymce/" target="_blank">详细可查看这里</a>)，可是总觉得是不太漂亮的解决方案。</p> <p>为了找是否有其它途径解决此问题，我查看了一下<a href="http://www.malsup.com/jquery/form" target="_blank">AjaxForm</a>的源代码，发现原来<a href="http://www.malsup.com/jquery/form" target="_blank">AjaxForm</a>作者已经为这问题提出了统一的解决方案，具体源代码如下：</p><pre>    <span style="color: #008000">// hook for manipulating the form data before it is extracted;</span>
    <span style="color: #008000">// convenient for use with rich editors like tinyMCE or FCKEditor</span>
    <span style="color: #0000ff">var</span> veto = {};
    <span style="color: #0000ff">this</span>.trigger('form-pre-serialize', [<span style="color: #0000ff">this</span>, options, veto]);
    <span style="color: #0000ff">if</span> (veto.veto) {
        log('ajaxSubmit: submit vetoed via form-pre-serialize trigger');
        <span style="color: #0000ff">return</span> <span style="color: #0000ff">this</span>;
   }</pre>
<p>果然，真的有对应的事件让我们可以在formData被序列号前将TinyMCE的数据更新到TextArea中。只要我们绑定form的form-pre-serialize事件即可。</p>
<p>于是一个我的代码就这样出来了：(对应FCKEditor类似)</p><pre>    <span style="color: #008000">// bind form using 'ajaxForm' </span>
    $('#commentForm').ajaxForm(options);
<span style="color: #008000">    // 绑定form-pre-serialize事件，在触发form-serilaize事件前保存tinyMCE的数据到textarea中</span>
    $('#commentForm').bind('form-pre-serialize', <span style="color: #0000ff">function</span>(event, form, options, veto) {
	tinyMCE.triggerSave();</pre><pre>    });</pre><pre>&nbsp;</pre><pre>^_^ 希望对你有用...</pre>
<div class="wlWriterSmartContent" id="scid:d7bf807d-7bb0-458a-811f-90c51817d5c2:7e442f99-9374-4b4d-95ce-ab75069c213d" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"><p><span class="TagSite">Technorati:</span> <a href="http://technorati.com/tag/jquey" rel="tag" class="tag">jquey</a>, <a href="http://technorati.com/tag/ajaxForm" rel="tag" class="tag">ajaxForm</a>, <a href="http://technorati.com/tag/ajax" rel="tag" class="tag">ajax</a>, <a href="http://technorati.com/tag/TinyMCE" rel="tag" class="tag">TinyMCE</a><br /><!-- StartInsertedTags: jquey,ajaxForm,ajax,TinyMCE :EndInsertedTags --></p></div><pre>&nbsp;</pre><img src ="http://www.cnblogs.com/fengmk2/aggbug/1216013.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42933/" target="_blank">[新闻]搞死开心网还是搞活他？</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>PE中的FileInfo究竟包含那些信息呢？</title><link>http://www.cnblogs.com/fengmk2/archive/2008/06/06/1214975.html</link><dc:creator>MK2</dc:creator><author>MK2</author><pubDate>Fri, 06 Jun 2008 02:40:00 GMT</pubDate><guid>http://www.cnblogs.com/fengmk2/archive/2008/06/06/1214975.html</guid><wfw:comment>http://www.cnblogs.com/fengmk2/comments/1214975.html</wfw:comment><comments>http://www.cnblogs.com/fengmk2/archive/2008/06/06/1214975.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/fengmk2/comments/commentRss/1214975.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/fengmk2/services/trackbacks/1214975.html</trackback:ping><description><![CDATA[<p>最近在收集PE的FileInfo信息，发现不是每个PE都会有，而且有也不一定全部都有，总结了样本，基本上包含一下信息：</p>
<p>LegalCopyright ：版权信息</p>
<p>InternalName: 内部名称</p>
<p>FileVersion：文件版本</p>
<p>CompanyName：公司名称</p>
<p>LegalTrademarks：注册商标</p>
<p>Comments：注释</p>
<p>ProductName：产品名称</p>
<p>ProductVersion：产品版本</p>
<p>FileDescription：文件描述</p>
<p>OriginalFilename：原始文件名</p>
<p>PrivateBuild：私有编译  (见样本3)</p>
<p>SpecialBuild：特殊编译</p>
<p>&nbsp;</p>
<p>几个特殊的信息：</p>
<p>BuildDate:&nbsp; 编译日期 (见样本1)</p>
<p>BuildNumber: 编译号(见样本1)</p>
<p>FileType: 文件类型 （本应该出现在VS_FIXEDFILEINFO中的，却又出现在FileInfo中，造成冲突，以VS_FIXEDFILEINFO中的为准）(见样本1)</p>
<p>OLESelfRegister:&nbsp; (见样本2)</p>
<p>文件的分析信息列表：</p>
<p>样本1:<a href="http://www.cnblogs.com/Files/fengmk2/35d417aa12d58edfc4ed0156e8ee855f.Nap.txt">http://www.cnblogs.com/Files/fengmk2/35d417aa12d58edfc4ed0156e8ee855f.Nap.txt</a> </p>
<p>样本2:<a href="http://www.cnblogs.com/Files/fengmk2/OLESelfRegister_QQ.exe.txt">http://www.cnblogs.com/Files/fengmk2/OLESelfRegister_QQ.exe.txt</a> </p>
<p>样本3:<a href="http://www.cnblogs.com/Files/fengmk2/PrivateBuild_8c26cc7d912ab9568b44a62291f7ac51.dll.txt">http://www.cnblogs.com/Files/fengmk2/PrivateBuild_8c26cc7d912ab9568b44a62291f7ac51.dll.txt</a> </p>
<div class="wlWriterSmartContent" id="scid:d7bf807d-7bb0-458a-811f-90c51817d5c2:952e6851-160f-4520-a4ec-237df9ae4c0f" style="margin: 0px; padding: 0px; display: inline;">
<p><span class="TagSite">Technorati:</span> <a href="http://technorati.com/tag/PE" rel="tag" class="tag">PE</a>, <a href="http://technorati.com/tag/FileInfo" rel="tag" class="tag">FileInfo</a><br />
<!-- StartInsertedTags: PE,FileInfo :EndInsertedTags --></p>
</div>
<img src ="http://www.cnblogs.com/fengmk2/aggbug/1214975.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42932/" target="_blank">[新闻]网络书店“新”军</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>Python: threading.local是全局变量但是它的值却在当前调用它的线程当中</title><link>http://www.cnblogs.com/fengmk2/archive/2008/06/04/1213958.html</link><dc:creator>MK2</dc:creator><author>MK2</author><pubDate>Wed, 04 Jun 2008 14:46:00 GMT</pubDate><guid>http://www.cnblogs.com/fengmk2/archive/2008/06/04/1213958.html</guid><wfw:comment>http://www.cnblogs.com/fengmk2/comments/1213958.html</wfw:comment><comments>http://www.cnblogs.com/fengmk2/archive/2008/06/04/1213958.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/fengmk2/comments/commentRss/1213958.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/fengmk2/services/trackbacks/1213958.html</trackback:ping><description><![CDATA[<p>在threading module中，有一个非常特别的类local。一旦在主线程实例化了一个local，它会一直活在主线程中，并且又主线程启动的子线程调用这个local实例时，它的值将会保存在相应的子线程的字典中。</p> <p>我们先看看测试代码：</p><pre>#!/usr/bin/python
# -*- coding: utf-8 -*-
# Description: test the threading.local <span style="color: #0000ff">class</span>
# Create: 2008-6-4
# Author: MK2[fengmk2@gmail.com]
from threading <span style="color: #0000ff">import</span> local, enumerate, Thread, currentThread

local_data = local()
local_data.<span style="color: #0000ff">name</span> = 'local_data'

<span style="color: #0000ff">class</span> TestThread(Thread):
        <span style="color: #0000ff">def</span> run(self):
                <span style="color: #0000ff">print</span> currentThread()
                <span style="color: #0000ff">print</span> local_data.__dict__
                local_data.<span style="color: #0000ff">name</span> = self.getName()
                local_data.add_by_sub_thread = self.getName()
                <span style="color: #0000ff">print</span> local_data.__dict__

<span style="color: #0000ff">if</span> __name__ == '<span style="color: #0000ff">__main__</span>':
        <span style="color: #0000ff">print</span> currentThread()
        <span style="color: #0000ff">print</span> local_data.__dict__
        
        t1 = TestThread()
        t1.<span style="color: #0000ff">start</span>()
        t1.<span style="color: #0000ff">join</span>()
        
        t2 = TestThread()
        t2.<span style="color: #0000ff">start</span>()
        t2.<span style="color: #0000ff">join</span>()
        
        <span style="color: #0000ff">print</span> currentThread()
        <span style="color: #0000ff">print</span> local_data.__dict__
</pre><pre>运行结果：</pre>
<p>&lt;_MainThread(MainThread, started)&gt;<br>{'name': 'local_data'}<br>&lt;TestThread(Thread-1, started)&gt;<br>{}<br>{'add_by_sub_thread': 'Thread-1', 'name': 'Thread-1'}<br>&lt;TestThread(Thread-2, started)&gt;<br>{}<br>{'add_by_sub_thread': 'Thread-2', 'name': 'Thread-2'}<br>&lt;_MainThread(MainThread, started)&gt;<br>{'name': 'local_data'}
<p>&nbsp; <p>主线程中的local_data并没有被改变，而子线程中的local_data各自都不相同。
<p>怎么这么神奇？local_data具有全局访问权，主线程，子线程都能访问它，但是它的值却是各当前线程有关，究竟什么奥秘在这里呢？
<p>查看了一下local的源代码，发现就神奇在_path()方法中:<pre><span style="color: #0000ff">def</span> _patch(self):
    key = object.__getattribute__(self, '_local__key')
    d = currentThread().__dict__.get(key)
    <span style="color: #0000ff">if</span> d is None:
        d = {}
        currentThread().__dict__[key] = d
        object.__setattr__(self, '__dict__', d)

        # we have a <span style="color: #0000ff">new</span> <span style="color: #0000ff">instance</span> dict, so call out __init__ <span style="color: #0000ff">if</span> we have
        # one
        cls = type(self)
        <span style="color: #0000ff">if</span> cls.__init__ is not object.__init__:
            args, kw = object.__getattribute__(self, '_local__args')
            cls.__init__(self, *args, **kw)
    <span style="color: #0000ff">else</span>:
        object.__setattr__(self, '__dict__', d)</pre><pre>&nbsp;</pre>
<p>每次调用local实例的属性前，local都会调用这个方法，找到它保存值的地方.</p>
<p>d = currentThread().__dict__.get(key)&nbsp; 就是这个地方，确定了local_data值的保存位置。所以子线程访问local_data时，并不是获取主线程的local_data的值，在子线程第一次访问它是，它是一个空白的字典对象，所以local_data.__dict__为 {}，就像我们的输出结果一样。</p>
<p>如果想在当前线程保存一个全局值，并且各自线程互不干扰，使用local类吧。</p>
<p>&nbsp;</p>
<div class="wlWriterSmartContent" id="scid:d7bf807d-7bb0-458a-811f-90c51817d5c2:a17f966d-5d9b-44d7-a014-46be9511ac7d" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"><p><span class="TagSite">Technorati:</span> <a href="http://technorati.com/tag/python" rel="tag" class="tag">python</a>, <a href="http://technorati.com/tag/local" rel="tag" class="tag">local</a>, <a href="http://technorati.com/tag/threading" rel="tag" class="tag">threading</a>, <a href="http://technorati.com/tag/thread" rel="tag" class="tag">thread</a><br /><!-- StartInsertedTags: python,local,threading,thread :EndInsertedTags --></p></div><img src ="http://www.cnblogs.com/fengmk2/aggbug/1213958.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42931/" target="_blank">[新闻]百度C2C电子商务平台“有啊”youa.com上线</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>Django tips: 没有了request对象，还能找到当前登录用户user吗？</title><link>http://www.cnblogs.com/fengmk2/archive/2008/06/04/1213727.html</link><dc:creator>MK2</dc:creator><author>MK2</author><pubDate>Wed, 04 Jun 2008 08:52:00 GMT</pubDate><guid>http://www.cnblogs.com/fengmk2/archive/2008/06/04/1213727.html</guid><wfw:comment>http://www.cnblogs.com/fengmk2/comments/1213727.html</wfw:comment><comments>http://www.cnblogs.com/fengmk2/archive/2008/06/04/1213727.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cnblogs.com/fengmk2/comments/commentRss/1213727.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/fengmk2/services/trackbacks/1213727.html</trackback:ping><description><![CDATA[<p>先来看看我们之前是怎样获取到当前登录user的：在view中，我们常常就会通过request对象来获取当前用户user的引用：</p>  <pre><span style="color: #0000ff">def</span> comment_add(request):
    # do something...
    <span style="color: #0000ff">user</span> = request.<span style="color: #0000ff">user</span>
    # to do .....</pre>

<p>&#160;</p>

<p>这样，确实很方便就能获取多用户的信息。可是，如果要做别的地方获取user呢？例如要在model中获取user呢？</p>

<pre><span style="color: #0000ff">class</span> Post(models.Model):
    title = models.CharField('Post标题', maxlength=100, db_index=True)
    create_date = models.DateTimeField('发布时间', default=datetime.now(), editable=False)
    modified_date = models.DateTimeField('最后修改时间', default=datetime.now(), editable=False)
    author = models.ForeignKey(User, verbose_name=&quot;<span style="color: #8b0000">作者</span>&quot;, editable=False)
    content = models.TextField('内容')
    last_visitor_IP = models.IPAddressField('最后的访问者IP', null=True, blank=True, editable=False)
    tags = models.ManyToManyField(Tag, verbose_name=&quot;<span style="color: #8b0000">the list of tags</span>&quot;, null=True, blank=True)
    slug = models.SlugField('自定义url', maxlength=100, null=True, blank=True)
    hits = models.IntegerField('点击数', editable=False, default=0)</pre>

<p>
  <br />可以看到，author是editable=False的，即我们想Post被保存是自动设置author为当前登录用户user。而这里没有request，怎样获取到这个user呢？找了一下django的文章，提到了使用<a title="django middleware" href="http://www.djangoproject.com/documentation/middleware/" target="_blank">middleware</a>来解决这个需求。</p>

<p>好吧，先在项目中创建一个&quot;<a title="django middleware" href="http://www.djangoproject.com/documentation/middleware/" target="_blank">middleware</a>&quot;模块（即带有一个空__init__.py文件的目录），接着创建&quot;threadlocals.py&quot;到此目录，代码如下：</p>

<pre>#!/usr/bin/python
# -*- coding: utf-8 -*-
# Description: thread locals middleware
# Create: 2008-6-4
try:
    from threading <span style="color: #0000ff">import</span> local
except ImportError:
    from django.utils._threading_local <span style="color: #0000ff">import</span> local

_thread_locals = local()
<span style="color: #0000ff">def</span> get_current_user():
    <span style="color: #0000ff">return</span> getattr(_thread_locals, '<span style="color: #0000ff">user</span>', None)

<span style="color: #0000ff">class</span> ThreadLocals(object):
    &quot;<span style="color: #8b0000"></span>&quot;&quot;Middleware that gets various objects from the
    request object and saves them in thread local storage.&quot;<span style="color: #8b0000"></span>&quot;&quot;
    <span style="color: #0000ff">def</span> process_request(self, request):
        _thread_locals.<span style="color: #0000ff">user</span> = getattr(request, '<span style="color: #0000ff">user</span>', None)</pre>

<p>接着将此middleware添加到项目中，打开setting.py，修改代码如下：</p>

<pre>MIDDLEWARE_CLASSES = (
    &quot;<span style="color: #8b0000">django.middleware.common.CommonMiddleware</span>&quot;,
    &quot;<span style="color: #8b0000">django.contrib.sessions.middleware.SessionMiddleware</span>&quot;,
    &quot;<span style="color: #8b0000">django.contrib.auth.middleware.AuthenticationMiddleware</span>&quot;,
    &quot;<span style="color: #8b0000">yourproject.middleware.threadlocals.ThreadLocals</span>&quot;, 
)</pre>
写到这里，发现这不类似与asp.net中的HttpModule吗？

<p>然后为了自动设置author为当前用户，我们需要重载post的save方法：</p>

<p>先导入middleware</p>

<pre>from net4.middleware <span style="color: #0000ff">import</span> threadlocals</pre>

<pre><span style="color: #0000ff">def</span> save(self):
    <span style="color: #0000ff">if</span> self.id is None:
        self.author = threadlocals.get_current_user()
    super(Post, self).save()</pre>

<p>编码工作完成了，还不快点进入admin看看是否可以正常工作了呢？</p>

<p>&#160;</p>

<p>其实大部分都是算直接在参考文章里哪过来的，呵呵，反正是花了点时间才找到，呵呵，就拿来主义，让大家一齐分享咯。</p>

<p>&#160;</p>

<p>希望对你有用！ ^_^</p>

<p>
  <br />本文参考：

  <br /><a href="http://code.djangoproject.com/wiki/CookBookThreadlocalsAndUser#MakingUserinfoavailableoutsiderequests">Making User info available outside requests </a></p>

<div class="wlWriterSmartContent" id="scid:d7bf807d-7bb0-458a-811f-90c51817d5c2:06308fc3-8761-4ed9-91da-c3863d3dd1fb" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px"><p><span class="TagSite">Technorati:</span> <a href="http://technorati.com/tag/django" rel="tag" class="tag">django</a>, <a href="http://technorati.com/tag/python" rel="tag" class="tag">python</a>, <a href="http://technorati.com/tag/middleware" rel="tag" class="tag">middleware</a>, <a href="http://technorati.com/tag/get_current_user" rel="tag" class="tag">get_current_user</a><br /><!-- StartInsertedTags: django,python,middleware,get_current_user :EndInsertedTags --></p></div><img src ="http://www.cnblogs.com/fengmk2/aggbug/1213727.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42931/" target="_blank">[新闻]百度C2C电子商务平台“有啊”youa.com上线</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>Python tips: 保存Unicode字符到文本文档</title><link>http://www.cnblogs.com/fengmk2/archive/2008/05/31/1211193.html</link><dc:creator>MK2</dc:creator><author>MK2</author><pubDate>Sat, 31 May 2008 05:36:00 GMT</pubDate><guid>http://www.cnblogs.com/fengmk2/archive/2008/05/31/1211193.html</guid><wfw:comment>http://www.cnblogs.com/fengmk2/comments/1211193.html</wfw:comment><comments>http://www.cnblogs.com/fengmk2/archive/2008/05/31/1211193.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/fengmk2/comments/commentRss/1211193.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/fengmk2/services/trackbacks/1211193.html</trackback:ping><description><![CDATA[<p>昨天在保存一些中文字符到文本文档时，发现一个很奇怪的现象。先看看代码：</p><pre>#coding=utf-8
<span style="color: #0000ff">import</span> <span style="color: #0000ff">os</span>

<span style="color: #0000ff">def</span> write_use_open(filepath):
    try:
        file = <span style="color: #0000ff">open</span>(filepath, 'wb')
        try:
            content = '中华人民共和国abcd \r\nee ?!&gt;??@@@!！！！！？？？￥@#%@%#xx学校ada\r\n'
            <span style="color: #0000ff">print</span> file.encoding
            <span style="color: #0000ff">print</span> file.newlines
            <span style="color: #0000ff">print</span> file.mode
            <span style="color: #0000ff">print</span> file.closed
            <span style="color: #0000ff">print</span> content
            file.<span style="color: #0000ff">write</span>(content)
        finally:
            file.<span style="color: #0000ff">close</span>()
            <span style="color: #0000ff">print</span> file.closed
    except IOError, e:
        <span style="color: #0000ff">print</span> e
    

<span style="color: #0000ff">if</span> __name__ == '<span style="color: #0000ff">__main__</span>':
    filepath = <span style="color: #0000ff">os</span>.<span style="color: #0000ff">path</span>.<span style="color: #0000ff">join</span>(<span style="color: #0000ff">os</span>.getcwd(), 'file.txt')
    write_use_open(filepath)</pre><pre>&nbsp;</pre><pre>开始我是IDLE编写的，并直接按F5运行，没发现问题，文件也被正确地保存，文件的编码类型也是utf-8.</pre><pre><a href="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/PythontipsUnicode_ADF6/image_2.png"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="167" alt="image" src="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/PythontipsUnicode_ADF6/image_thumb.png" width="339" border="0"></a> </pre><a href="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/PythontipsUnicode_ADF6/image_4.png"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="195" alt="image" src="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/PythontipsUnicode_ADF6/image_thumb_1.png" width="413" border="0"></a> <pre>可是我用命令行运行，却发现显示出现乱码了，然后在打开文件发现文件被正确保存了，编码还是utf-8：</pre><pre><a href="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/PythontipsUnicode_ADF6/image_6.png"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="162" alt="image" src="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/PythontipsUnicode_ADF6/image_thumb_2.png" width="437" border="0"></a> </pre><pre>我想问题是命令行不能自动识别字符编码吧，因为IDLE显示是正确的，它支持utf-8。</pre><pre>&nbsp;</pre><pre>于是我修改了代码，在字符串前加了'u'，表明content是unicode:</pre>
<p>content = u'中华人民共和国abcd \r\nee ?!&gt;??@@@!！！！！？？？￥@#%@%#xx学校ada\r\n' </p>
<p>可是运行发现，命令行是正确显示了，但是却出现异常：</p>
<p><a href="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/PythontipsUnicode_ADF6/image_8.png"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="205" alt="image" src="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/PythontipsUnicode_ADF6/image_thumb_3.png" width="644" border="0"></a> </p>
<p>很明显，content里包含了非ASCII码字符，肯定不能使用ASCII来进行编码的，write方法是默认使用ascii来编码保存的。</p>
<p>很容易就可以想到，在保存之前，先对unicode字符进行编码，我选择utf-8</p><pre>#coding=utf-8
<span style="color: #0000ff">import</span> <span style="color: #0000ff">os</span>

<span style="color: #0000ff">def</span> write_use_open(filepath):
    try:
        file = <span style="color: #0000ff">open</span>(filepath, 'wb')
        try:
            content = u'中华人民共和国abcd \r\nee ?!&gt;??@@@!！！！！？？？￥@#%@%#xx学校ada\r\n'
            <span style="color: #0000ff">print</span> file.encoding
            <span style="color: #0000ff">print</span> file.newlines
            <span style="color: #0000ff">print</span> file.mode
            <span style="color: #0000ff">print</span> file.closed
            <span style="color: #0000ff">print</span> content
            <span style="color: #0000ff">print</span> unicode.<span style="color: #0000ff">encode</span>(content, 'utf-8')
            file.<span style="color: #0000ff">write</span>(unicode.<span style="color: #0000ff">encode</span>(content, 'utf-8'))
        finally:
            file.<span style="color: #0000ff">close</span>()
            <span style="color: #0000ff">print</span> file.closed
    except IOError, e:
        <span style="color: #0000ff">print</span> e
    
<span style="color: #0000ff">if</span> __name__ == '<span style="color: #0000ff">__main__</span>':
    filepath = <span style="color: #0000ff">os</span>.<span style="color: #0000ff">path</span>.<span style="color: #0000ff">join</span>(<span style="color: #0000ff">os</span>.getcwd(), 'file.txt')
    write_use_open(filepath)</pre><pre>&nbsp;</pre><pre>看看运行结果：</pre><pre><a href="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/PythontipsUnicode_ADF6/image_10.png"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="204" alt="image" src="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/PythontipsUnicode_ADF6/image_thumb_4.png" width="441" border="0"></a> </pre><pre>OK了打开文档也是正确的。</pre><pre>读取文件又怎样？同样道理，只是这次不是编码了，而解码：</pre><pre><span style="color: #0000ff">def</span> read_use_open(filepath):
    try:
        file = <span style="color: #0000ff">open</span>(filepath, 'rb')
        try:
            content = file.<span style="color: #0000ff">read</span>()
            content_decode = unicode(content, 'utf-8')
            <span style="color: #0000ff">print</span> 'original text'
            <span style="color: #0000ff">print</span> content
            <span style="color: #0000ff">print</span> '<span style="color: #0000ff">decode</span> using utf-8'
            <span style="color: #0000ff">print</span> content_decode
        finally:
            file.<span style="color: #0000ff">close</span>()
    except IOError, e:
        <span style="color: #0000ff">print</span> e
    
<span style="color: #0000ff">if</span> __name__ == '<span style="color: #0000ff">__main__</span>':
    filepath = <span style="color: #0000ff">os</span>.<span style="color: #0000ff">path</span>.<span style="color: #0000ff">join</span>(<span style="color: #0000ff">os</span>.getcwd(), 'file.txt')
    write_use_open(filepath)
    <span style="color: #0000ff">print</span> '<span style="color: #0000ff">read</span> file ---------------------------'
    read_use_open(filepath)</pre>
<p><a href="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/PythontipsUnicode_ADF6/image_12.png"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="141" alt="image" src="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/PythontipsUnicode_ADF6/image_thumb_5.png" width="434" border="0"></a> </p>
<p>为什么不直接在open的时候就解码呢？呵呵，可以啊，可以使用<a href="http://docs.python.org/lib/module-codecs.html" target="_blank">codecs</a>的open方法<br></p><pre><span style="color: #0000ff">import</span> codecs
<span style="color: #0000ff">def</span> read_use_codecs_open(filepath):
    try:
        file = codecs.<span style="color: #0000ff">open</span>(filepath, 'rb', 'utf-8')
        try:
            <span style="color: #0000ff">print</span> 'using codecs.<span style="color: #0000ff">open</span>'
            content = file.<span style="color: #0000ff">read</span>()
            <span style="color: #0000ff">print</span> content
        finally:
            file.<span style="color: #0000ff">close</span>()
    except IOError, e:
        <span style="color: #0000ff">print</span> e</pre><pre><a href="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/PythontipsUnicode_ADF6/image_14.png"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="67" alt="image" src="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/PythontipsUnicode_ADF6/image_thumb_6.png" width="362" border="0"></a> </pre><pre>&nbsp;</pre><pre>好了，希望对你有用。</pre><pre>&nbsp;</pre><pre>本文参考：<a href="http://www.amk.ca/python/howto/unicode" target="_blank">Unicode HOWTO</a></pre>
<div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:0b666369-d3bd-4a53-8806-f216fc5cb445" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px">Technorati 标签: <a href="http://technorati.com/tags/Python" rel="tag">Python</a>,<a href="http://technorati.com/tags/unicode" rel="tag">unicode</a>,<a href="http://technorati.com/tags/utf-8" rel="tag">utf-8</a>,<a href="http://technorati.com/tags/ascii" rel="tag">ascii</a>,<a href="http://technorati.com/tags/codecs" rel="tag">codecs</a>,<a href="http://technorati.com/tags/open" rel="tag">open</a></div><img src ="http://www.cnblogs.com/fengmk2/aggbug/1211193.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42930/" target="_blank">[新闻]Silverlight 2.0正式版下周发布</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>Python tips: 什么是*args和**kwargs？</title><link>http://www.cnblogs.com/fengmk2/archive/2008/04/21/1163766.html</link><dc:creator>MK2</dc:creator><author>MK2</author><pubDate>Mon, 21 Apr 2008 05:34:00 GMT</pubDate><guid>http://www.cnblogs.com/fengmk2/archive/2008/04/21/1163766.html</guid><wfw:comment>http://www.cnblogs.com/fengmk2/comments/1163766.html</wfw:comment><comments>http://www.cnblogs.com/fengmk2/archive/2008/04/21/1163766.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/fengmk2/comments/commentRss/1163766.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/fengmk2/services/trackbacks/1163766.html</trackback:ping><description><![CDATA[<p>先来看个例子：</p>  <pre><span style="color: #0000ff">def</span> foo(*args, **kwargs):
    <span style="color: #0000ff">print</span> 'args = ', args
    <span style="color: #0000ff">print</span> 'kwargs = ', kwargs
    <span style="color: #0000ff">print</span> '---------------------------------------'

<span style="color: #0000ff">if</span> __name__ == '<span style="color: #0000ff">__main__</span>':
    foo(1,2,3,4)
    foo(a=1,b=2,c=3)
    foo(1,2,3,4, a=1,b=2,c=3)
    foo('a', 1, None, a=1, b='2', c=3)</pre>

<pre>输出结果如下：</pre>

<p>args =&#160; (1, 2, 3, 4) 
  <br />kwargs =&#160; {} 

  <br />--------------------------------------- 

  <br />args =&#160; () 

  <br />kwargs =&#160; {'a': 1, 'c': 3, 'b': 2} 

  <br />--------------------------------------- 

  <br />args =&#160; (1, 2, 3, 4) 

  <br />kwargs =&#160; {'a': 1, 'c': 3, 'b': 2} 

  <br />--------------------------------------- 

  <br />args =&#160; ('a', 1, None) 

  <br />kwargs =&#160; {'a': 1, 'c': 3, 'b': '2'} 

  <br />---------------------------------------</p>

<p>可以看到，这两个是python中的可变参数。*args表示任何多个无名参数，它是一个tuple；**kwargs表示关键字参数，它是一个dict。并且同时使用*args和**kwargs时，必须*args参数列要在**kwargs前，像foo(a=1, b='2', c=3, a', 1, None, )这样调用的话，会提示语法错误&#8220;SyntaxError: non-keyword arg after keyword arg&#8221;。</p>

<p>&#160;</p>

<p>呵呵，知道*args和**kwargs是什么了吧。还有一个很漂亮的用法，就是创建字典：</p>

<pre>    <span style="color: #0000ff">def</span> kw_dict(**kwargs):
        <span style="color: #0000ff">return</span> kwargs
    <span style="color: #0000ff">print</span> kw_dict(a=1,b=2,c=3) == {'a':1, 'b':2, 'c':3}</pre>

<p> 其实python中就带有dict类，使用dict(a=1,b=2,c=3)即可创建一个字典了。</p>

<p>&#160;</p>

<p>&#8220;人生苦短，我用python。&#8221;</p>

<div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:b82b196a-8d15-4163-af83-dd399d9e77e1" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px">Technorati 标签: <a href="http://technorati.com/tags/python" rel="tag">python</a>,<a href="http://technorati.com/tags/tuple" rel="tag">tuple</a>,<a href="http://technorati.com/tags/dict" rel="tag">dict</a>,<a href="http://technorati.com/tags/*args" rel="tag">*args</a>,<a href="http://technorati.com/tags/**kwargs" rel="tag">**kwargs</a></div><img src ="http://www.cnblogs.com/fengmk2/aggbug/1163766.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42925/" target="_blank">[新闻]Wikipedia“变心”，力挺Ubuntu</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>博客园的RSS请求不支持Last-Modified</title><link>http://www.cnblogs.com/fengmk2/archive/2008/04/19/1161265.html</link><dc:creator>MK2</dc:creator><author>MK2</author><pubDate>Sat, 19 Apr 2008 08:10:00 GMT</pubDate><guid>http://www.cnblogs.com/fengmk2/archive/2008/04/19/1161265.html</guid><wfw:comment>http://www.cnblogs.com/fengmk2/comments/1161265.html</wfw:comment><comments>http://www.cnblogs.com/fengmk2/archive/2008/04/19/1161265.html#Feedback</comments><slash:comments>7</slash:comments><wfw:commentRss>http://www.cnblogs.com/fengmk2/comments/commentRss/1161265.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/fengmk2/services/trackbacks/1161265.html</trackback:ping><description><![CDATA[<p>今天在测试读取RSS时，使用到自己在博客园的RSS链接来做测试，发现使用Last-Modified方式优化时，RSS每次返回都会更新Last-Modified。</p>  <p>以下是用Fiddler对几次请求的截获结果：</p>  <p>第一次请求，客户端不会添加头If-Modified-Since头，这是肯定的。</p>  <p><a href="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/RSSLastModified_E372/image_6.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="336" alt="image" src="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/RSSLastModified_E372/image_thumb_2.png" width="582" border="0" /></a> </p>  <p>服务器端返回了Last-Modified，并且响应代码是200，这样客户端可以在下次请求中使用。</p>  <p>&#160;</p>  <p>第二次请求，客户端根据上次请求返回的Last-Modified，添加If-Modified-Since头。</p>  <p><a href="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/RSSLastModified_E372/image_4.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="380" alt="image" src="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/RSSLastModified_E372/image_thumb_1.png" width="583" border="0" /></a> </p>  <p>服务器返回结果并不是我们预料中的304，却依然是200，也就是说全部内容又重新下载了一遍，If-Modified-Since请求头并未起作用。原因是什么？看看服务器返回的Last-Modified就知道，RSS内容并未更新，长度还是67672，本应该Last-Modified与第一次的Last-Modified相等才对的。</p>  <p>&#160;</p>  <p>再进行一次测试：</p>  <p><a href="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/RSSLastModified_E372/image_8.png"><img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="377" alt="image" src="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/RSSLastModified_E372/image_thumb_3.png" width="584" border="0" /></a> </p>  <p>结果和上面一样，Last-Modified有变化了。</p>  <p>&#160;</p>  <p>呵呵，Last-Modified得到支持，将会为我们双方都节省许多带宽的。与Last-Modified类似的，就是Etag头。想详细了解什么是Last-Modified和Etag，可参考：<a href="http://blog.csdn.net/houjianxun/archive/2007/09/25/1799328.aspx" target="_blank">如何利用客户端缓存对网站进行优化?</a> </p>  <div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:263f2899-7d97-4917-87c4-67a9a1959004" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px">Technorati 标签: <a href="http://technorati.com/tags/RSS" rel="tag">RSS</a>,<a href="http://technorati.com/tags/Last-Modified" rel="tag">Last-Modified</a>,<a href="http://technorati.com/tags/Etag" rel="tag">Etag</a>,<a href="http://technorati.com/tags/Request" rel="tag">Request</a>,<a href="http://technorati.com/tags/Fiddler" rel="tag">Fiddler</a></div><img src ="http://www.cnblogs.com/fengmk2/aggbug/1161265.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42924/" target="_blank">[新闻]“不可破解”的加密技术出</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>Django tips: 查看当前Request所执行的所有SQL</title><link>http://www.cnblogs.com/fengmk2/archive/2008/04/18/1160475.html</link><dc:creator>MK2</dc:creator><author>MK2</author><pubDate>Fri, 18 Apr 2008 13:38:00 GMT</pubDate><guid>http://www.cnblogs.com/fengmk2/archive/2008/04/18/1160475.html</guid><wfw:comment>http://www.cnblogs.com/fengmk2/comments/1160475.html</wfw:comment><comments>http://www.cnblogs.com/fengmk2/archive/2008/04/18/1160475.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cnblogs.com/fengmk2/comments/commentRss/1160475.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/fengmk2/services/trackbacks/1160475.html</trackback:ping><description><![CDATA[<p>究竟在一次Request中，Django对数据库执行了那些查询和操作呢？呵呵，Django早就为我们想好了这个问题，使用<a href="http://www.djangoproject.com/documentation/0.96/templates_python/#django-core-context-processors-debug">django.core.context_processors.debug</a>模块即可。</p>  <p>在setting中设置：</p>  <p>TEMPLATE_CONTEXT_PROCESSORS = (   <br />&#160;&#160;&#160; &quot;django.core.context_processors.debug&quot;, #debug 一次请求调用到多少SQL语句&quot;,    <br />) </p>  <p>并设置能看到次debug信息的请求IP：</p>  <p>INTERNAL_IPS = ('127.0.0.1',)</p>  <p>我们就可以在模板中设置一下，即可：</p>  <pre>{% endblock %}
{% if sql_queries %}
<span style="color: #0000ff">&lt;</span><span style="color: #800000">h3</span><span style="color: #0000ff">&gt;</span>SQL excute in this Request<span style="color: #0000ff">&lt;/</span><span style="color: #800000">h3</span><span style="color: #0000ff">&gt;</span>
<span style="color: #008000">&lt;!-- debug: show the sql excute in this request --&gt;</span>
{% for query in sql_queries %}<span style="color: #0000ff">&lt;</span><span style="color: #800000">h3</span><span style="color: #0000ff">&gt;</span>Excute times: {{query.time}}<span style="color: #0000ff">&lt;/</span><span style="color: #800000">h3</span><span style="color: #0000ff">&gt;</span>
<span style="color: #0000ff">&lt;</span><span style="color: #800000">p</span><span style="color: #0000ff">&gt;</span>
<span style="color: #0000ff">&lt;</span><span style="color: #800000">code</span><span style="color: #0000ff">&gt;</span>
{{query.sql}}
<span style="color: #0000ff">&lt;/</span><span style="color: #800000">code</span><span style="color: #0000ff">&gt;</span>
<span style="color: #0000ff">&lt;/</span><span style="color: #800000">p</span><span style="color: #0000ff">&gt;</span>
{% endfor %}<span style="color: #008000">&lt;!-- debug ends here --&gt;</span>
{% endif %}</pre>

<pre>以上只会在你设置了TEMPLATE_DEBUG = DEBUG，和请求IP在INTERNAL_IPS设置过，才会显示。</pre>

<pre>看看一个截图吧：</pre>

<pre><a href="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/DjangotipsRequestSQL_1302D/image_2.png"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="498" alt="image" src="http://www.cnblogs.com/images/cnblogs_com/fengmk2/WindowsLiveWriter/DjangotipsRequestSQL_1302D/image_thumb.png" width="530" border="0" /></a> </pre>

<pre>呵呵，看到了对<a href="http://www.djangoproject.com/documentation/0.96/sessions/">Session</a>的查询。</pre>

<pre>不错吧，这样我们可以对实际执行的SQL有底了。</pre>

<div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:f36d0ebd-8e12-4ffc-917a-09245cfa3a6b" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px">Technorati 标签: <a href="http://technorati.com/tags/Django" rel="tag">Django</a>,<a href="http://technorati.com/tags/SQL" rel="tag">SQL</a>,<a href="http://technorati.com/tags/Request" rel="tag">Request</a>,<a href="http://technorati.com/tags/Session" rel="tag">Session</a>,<a href="http://technorati.com/tags/tips" rel="tag">tips</a>,<a href="http://technorati.com/tags/python" rel="tag">python</a></div><img src ="http://www.cnblogs.com/fengmk2/aggbug/1160475.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42923/" target="_blank">[新闻]13款Firefox Gmail扩展</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>给User添加Profile in Django</title><link>http://www.cnblogs.com/fengmk2/archive/2008/04/10/1147122.html</link><dc:creator>MK2</dc:creator><author>MK2</author><pubDate>Thu, 10 Apr 2008 09:18:00 GMT</pubDate><guid>http://www.cnblogs.com/fengmk2/archive/2008/04/10/1147122.html</guid><wfw:comment>http://www.cnblogs.com/fengmk2/comments/1147122.html</wfw:comment><comments>http://www.cnblogs.com/fengmk2/archive/2008/04/10/1147122.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/fengmk2/comments/commentRss/1147122.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/fengmk2/services/trackbacks/1147122.html</trackback:ping><description><![CDATA[<p>1. 创建app</p>  <p>manage.py startapp users</p>  <p>2. 编写profile model</p>  <pre>from django.db <span style="color: #0000ff">import</span> models
from django.contrib.auth.models <span style="color: #0000ff">import</span> User

GENDER_CHOICES = (
                  ('M', '男'),
                  ('F', '女'),
                  )

<span style="color: #0000ff">class</span> UserProfile(models.Model):
    # 这个字段是必须的，并且只能为user，且要添加外键关联到User
    <span style="color: #0000ff">user</span> = models.ForeignKey(User, unique=True, verbose_name='用户的额外信息')
    # 以下可以按各自需求来定义
    tel = models.CharField('电话', maxlength=20, blank=True, null=True)
    mobile = models.CharField('移动电话', maxlength=20, blank=True, null=True)
    address = models.CharField('家庭地址', maxlength=100, blank=True, null=True)
    website = models.URLField('个人主页', blank=True, null=True)
    birthday = models.DateField('出生日期', blank=True, null=True)
    gender = models.CharField('性别', maxlength=1, choices=GENDER_CHOICES, radio_admin=True, default='M')
    blog = models.URLField('个人主页', blank=True, null=True)
    QQ = models.CharField('QQ', maxlength=50, blank=True, null=True)
    MSN = models.CharField(maxlength=50, blank=True, null=True)
    IM = models.CharField(maxlength=50, blank=True, null=True)
    position = models.CharField('目前所在地', maxlength=200, blank=True, null=True)
    country = models.CharField('目前所在国家', maxlength=50, blank=True, null=True, default='中国')</pre>

<p>3. 设置AUTH_PROFILE_MODULE</p>

<p>AUTH_PROFILE_MODULE = 'users.UserProfile' #不区分大小写的</p>

<p>4. 添加INSTALLED_APPS</p>

<p>INSTALLED_APPS = (</p>

<p> ...............
  <br />&#160;&#160;&#160; 'web.users',

  <br />)</p>

<p>5. 同步数据库</p>

<p>manage.py syncdb</p>

<p>&#160;</p>

<p>只需使用User.get_profile()方法即可返回对应的UserPrfile对象实例了。</p>

<div class="wlWriterSmartContent" id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:fc7c0808-0774-4c61-be3e-aa90c3e431b1" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px">Technorati 标签: <a href="http://technorati.com/tags/django" rel="tag">django</a>,<a href="http://technorati.com/tags/python" rel="tag">python</a>,<a href="http://technorati.com/tags/web" rel="tag">web</a>,<a href="http://technorati.com/tags/user" rel="tag">user</a>,<a href="http://technorati.com/tags/profile" rel="tag">profile</a>,<a href="http://technorati.com/tags/userprofile" rel="tag">userprofile</a></div><img src ="http://www.cnblogs.com/fengmk2/aggbug/1147122.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42922/" target="_blank">[新闻]支持鼠标手势的Chrome中文修改版</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>工欲善其事必先利其器 - Python开发篇</title><link>http://www.cnblogs.com/fengmk2/archive/2008/04/10/1146270.html</link><dc:creator>MK2</dc:creator><author>MK2</author><pubDate>Thu, 10 Apr 2008 02:12:00 GMT</pubDate><guid>http://www.cnblogs.com/fengmk2/archive/2008/04/10/1146270.html</guid><wfw:comment>http://www.cnblogs.com/fengmk2/comments/1146270.html</wfw:comment><comments>http://www.cnblogs.com/fengmk2/archive/2008/04/10/1146270.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/fengmk2/comments/commentRss/1146270.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/fengmk2/services/trackbacks/1146270.html</trackback:ping><description><![CDATA[<p>首先，写Python代码的IDE有许多，呵呵，至于功能强大的肯定是<a href="http://www.eclipse.org/">Eclipse</a> + <a href="http://www.fabioz.com/pydev">pydev</a>了，以下是pydev的显著的特性：</p>
<h5>Some feature-highlights</h5>
<ul>
<li><a href="http://www.fabioz.com/pydev/manual_adv_refactoring.html"><strong>Rename refactoring</strong></a>: renames all occurrences for some token in your workspace -- with preview and undo/redo (<strong>1.2.6</strong>) </li>
<li><strong>Support for python 2.5</strong> (<strong>1.2.3</strong>) </li>
<li><a href="http://www.fabioz.com/pydev/manual_adv_markoccurrences.html"><strong>Mark Occurrences</strong></a> is able to highlight all the occurrences of some token in a file (<strong>1.0.7</strong>) </li>
<li><a href="http://www.fabioz.com/pydev/manual_adv_renameoccurrences.html"><strong>Rename Occurrences</strong></a>: renames all the occurrences of some token in a file (<strong>Ctrl+2+R</strong> -- <strong>1.0.7</strong>) </li>
<li><a href="http://www.fabioz.com/pydev/manual_adv_interactive_console.html"><strong>Interactive Console</strong> binded to the Pydev Editor</a> (<strong>1.0.4</strong>) </li>
<li><strong><a href="http://www.fabioz.com/pydev/manual_adv_open_decl_quick.html">Open Definition Quick-outline</a></strong> (<strong>1.0.3</strong>) </li>
<li><strong><a href="http://www.fabioz.com/pydev/manual_adv_debug_console.html">Debug console</a></strong> (<strong>1.0.2</strong> -- allows interactive probing in suspended mode) <a href="http://www.fabioz.com/pydev/manual_adv_debug_console.html"></a></li>
<li><strong><a href="http://www.fabioz.com/pydev/manual_adv_complnoctx.html">Code completion with auto-import</a></strong> </li>
<li><strong><a href="http://www.fabioz.com/pydev/manual_adv_code_analysis.html">Code analysis</a></strong> (PyLint replacement, but much faster) </li>
<li><strong><a href="http://www.fabioz.com/pydev/manual_adv_assistants.html">Quick-Fix</a></strong> for problems found in code analysis </li>
<li><strong><a href="http://www.fabioz.com/pydev/manual_adv_gotodef.html">Go to definition</a></strong> (Bycicle Repair Man replacement, but much more reliable) </li>
<li><strong><a href="http://www.fabioz.com/pydev/manual_adv_remote_debugger.html">Debug server</a></strong> (allows debugging scripts not lauched from within Eclipse) </li>
<li><strong><a href="http://www.fabioz.com/pydev/manual_adv_complauto.html">Keywords presented as auto-completions</a></strong> as you type </li>
<li><strong><a href="http://www.fabioz.com/pydev/manual_adv_quick_outline.html">Quick-outline</a></strong> </li>
</ul>
<p>&nbsp;</p>
<p>接着，我选择使用Django框架做Web开发的话，怎么能少了对HTML, CSS, JavaScript的编辑器呢?呵呵，同样是Eclipse的插件：<a href="http://www.aptana.com/docs/index.php/Plugging_Aptana_into_an_existing_Eclipse_configuration">Aptana</a> ，强大的智能提示，肯定帮助我们加快开发的速度和提高开发体验的（呵呵，我们也要良好的用户体验喔）。</p>
<p>&nbsp;</p>
<p>最后不用说，就是SVN，Eclipse的SVN插件：<a href="http://subclipse.tigris.org">subclipse</a>，这样3样工具，足够了。</p>
<p>&nbsp;</p>
<p>PS: 还有可选的，UML建模工具：<a href="http://www.omondo.com/">EclipseUML</a>；Mylyn: http://www.eclipse.org/mylyn/downloads/</p>
<p>&nbsp;</p>
<p><a href="http://www.omondo.com/"><br /></a></p>
<div id="scid:0767317B-992E-4b12-91E0-4F059A8CECA8:24c8e6ab-c679-4b38-90c6-5c40df63ba87" class="wlWriterSmartContent" style="padding-right: 0px; display: inline; padding-left: 0px; padding-bottom: 0px; margin: 0px; padding-top: 0px">Technorati 标签: <a rel="tag" href="http://technorati.com/tags/python">python</a>,<a rel="tag" href="http://technorati.com/tags/django">django</a>,<a rel="tag" href="http://technorati.com/tags/eclipse">eclipse</a>,<a rel="tag" href="http://technorati.com/tags/pydev">pydev</a>,<a rel="tag" href="http://technorati.com/tags/svn">svn</a>,<a rel="tag" href="http://technorati.com/tags/subclipse">subclipse</a>,<a rel="tag" href="http://technorati.com/tags/aptana">aptana</a>,<a rel="tag" href="http://technorati.com/tags/web">web</a></div><img src ="http://www.cnblogs.com/fengmk2/aggbug/1146270.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42922/" target="_blank">[新闻]支持鼠标手势的Chrome中文修改版</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item></channel></rss>