﻿<?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>BlogJava-海上月明-随笔分类-Python</title><link>http://www.blogjava.net/pts/category/19954.html</link><description>editer by sun</description><language>zh-cn</language><lastBuildDate>Fri, 21 Nov 2014 08:27:31 GMT</lastBuildDate><pubDate>Fri, 21 Nov 2014 08:27:31 GMT</pubDate><ttl>60</ttl><item><title>PYTON与EXCEL：使用pyExcelerator来读写 Excel文件</title><link>http://www.blogjava.net/pts/archive/2014/11/21/420390.html</link><dc:creator>pts</dc:creator><author>pts</author><pubDate>Fri, 21 Nov 2014 01:35:00 GMT</pubDate><guid>http://www.blogjava.net/pts/archive/2014/11/21/420390.html</guid><wfw:comment>http://www.blogjava.net/pts/comments/420390.html</wfw:comment><comments>http://www.blogjava.net/pts/archive/2014/11/21/420390.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/pts/comments/commentRss/420390.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/pts/services/trackbacks/420390.html</trackback:ping><description><![CDATA[【FROM】<a href="http://blog.csdn.net/suofiya2008/article/details/5589627">http://blog.csdn.net/suofiya2008/article/details/5589627</a>&nbsp;&nbsp;&nbsp; <br />我们写程序，经常会需要输出一些数据进行保存，对于格式固定的大量数据，Excel表格会是比较好的一个选择。如果你需要在Python下写入Excel文件，那么就需要用到PyExcelerator了。<p>PyExcelerator是一个第三方库，用来处理Excel文件。它的优点是：</p><p>简单易用，上手快。</p><p>写操作很方便，适合用来生成Excel文件记录数据。</p><p>不需要WinCOM支持，没装Office也 可以生成Excel表格</p><p>当然，PyExcelerator也是有缺点的，它所提供的读写操作方式相对简单，要对已有的Excel文件进行修改，就显得比较麻烦了。</p><p>如果要对已有的Excel表格进行较复杂的修改操作，选择PyExcelerator就不太合适了，这时候可以试试另外的方法。比如使用pywin32通过WinCOM来操作Excel表格，或者使用xlrd。</p><p>PyExcelerator的官方主页是<a href="http://sourceforge.net/projects/pyexcelerator">http://sourceforge.net/projects/pyexcelerator</a>，程序包中并没有太多的教程文档，不过包含了一些简单的示范操作的小例子，如果需要更详细的信息，就只能读源代码了。</p><p>&nbsp;</p><p>一。初始pyExcelerator</p><p>&nbsp;</p><p>&nbsp;&nbsp;&nbsp;&nbsp; pyExcelerator是一个基于python的可以读写excel文件的产品。和xlrd相比，pyExcelrator的主要特点在于可以对excel文件进行写操作。但是在读取数据方面，功能就没有xlrd强大了。</p><p>　　pyExcelerator只能提供关于表单内容的基础数据，对于表单行数、列数、单元格数据类型等详细信息都没有提供访问接口。因此开发人员必须了解表单的具体结构，才对表单中的数据进行正确的分析转换。</p><p>　　将pyExcelerator产品包（pyexcelerator-0.6.3a.tgz）上传到服务器上之后解压缩，然后在产品目录下键入如下命令：</p><pre>   <span style="background-color: rgb(136, 136, 136);">  <span style="color: rgb(255, 0, 0);"># python setup.py install</span>






</span>
在命令行中，你将看到一连串的running，creating，copying，byte&#8212;compiling命令结果，吧啦吧啦。。。



最后一行出现

Writing C:/Python26/Lib/site-packages/pyExcelerator-0.6.4.1-py2.6.egg-info



说明已经将插件安装到你的python环境中了，至此安装完成。



这里提一个小例子：</pre><div class="wp_syntax"><div class="code"><div class="dp-highlighter bg_python"><div class="bar"><div class="tools"><strong>[python]</strong> <a title="view plain" class="ViewSource" href="http://blog.csdn.net/suofiya2008/article/details/5589627#"><u><font color="#0066cc">view plain</font></u></a><a title="copy" class="CopyToClipboard" href="http://blog.csdn.net/suofiya2008/article/details/5589627#"><u><font color="#0066cc">copy</font></u></a><a title="print" class="PrintSource" href="http://blog.csdn.net/suofiya2008/article/details/5589627#"><u><font color="#0066cc">print</font></u></a><a title="?" class="About" href="http://blog.csdn.net/suofiya2008/article/details/5589627#"><u><font color="#0066cc">?</font></u></a></div></div><ol class="dp-py"><li class="alt"><span class="keyword">from</span><span>&nbsp;pyExcelerator&nbsp;</span><span class="keyword">import</span><span>&nbsp;*&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li class="alt"><span>w&nbsp;=&nbsp;Workbook()&nbsp;<span class="comment">#创建一个工作簿</span><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li class="alt"><span>ws&nbsp;=&nbsp;w.add_sheet(<span class="string">'Hey,&nbsp;Hades'</span><span>)&nbsp;</span><span class="comment">#创建一个工作表</span><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li class="alt"><span>ws.write(<span class="number">0</span><span>,</span><span class="number">0</span><span>,</span><span class="string">'bit'</span><span>)&nbsp;</span><span class="comment">#在1行1列写入bit</span><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li class="alt"><span>ws.write(<span class="number">0</span><span>,</span><span class="number">1</span><span>,</span><span class="string">'huang'</span><span>)&nbsp;</span><span class="comment">#在1行2列写入huang</span><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li class="alt"><span>ws.write(<span class="number">1</span><span>,</span><span class="number">0</span><span>,</span><span class="string">'xuan'</span><span>)&nbsp;</span><span class="comment">#在2行1列写入xuan</span><span>&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;</span></li><li class="alt"><span>w.save(<span class="string">'mini.xls'</span><span>)&nbsp;</span><span class="comment">#保存</span><span>&nbsp;&nbsp;</span></span></li></ol></div><pre class="python" style="text-align: left; font-family: monospace; display: none;" name="code">from pyExcelerator import *



w = Workbook() #创建一个工作簿



ws = w.add_sheet('Hey, Hades') #创建一个工作表



ws.write(0,0,'bit') #在1行1列写入bit



ws.write(0,1,'huang') #在1行2列写入huang



ws.write(1,0,'xuan') #在2行1列写入xuan



w.save('mini.xls') #保存</pre><h5><a name="t0"></a>二、Excel文件读取</h5><blockquote><p>from pyExcelerator import *<br /> sheets = parse_xls('d:/a.xls')</p></blockquote><p>很简单，与 xlrd 不同。xlrd 需要先调用book = xlrd.open_workbook(filename)打开文档，然后再调用sh= book.sheet_by_index(i)来得到第几个sheet，然后再使用sh.cell_value(i,j)得到i行j列的单元格的值。操作多了一点。而上面的parse_xls(filename)则直接返回一个列表，每一项就是一个sheet的数据。每项是一个二元组(表名,单元格数据)。其中单元格数据为一个字典，键值就是单元格的索引(i,j)。如果某个单元格无数据，那么就不存在这个值。看似简单，但从处理上不象&nbsp; xlrd 一样，可以知道每个sheet的最大行数和列数，然后进行循环。而使用 pyExcelerator好象没有最大行数和列数，再加上空数据又不存在，因此在处理上相对麻烦一些。这样在处理上还需要注意。它与 xlrd 一样都支持 unicode，但好象没有 xlrd 一样方便地判断单元格的类型的方法，感觉还是 xlrd在功能上可能要强一些。当然这只是个人感觉，再加上只是看了看例子，并没有怎么使用。 </p><h5><a name="t1"></a>三、Excel文件写入</h5><p>这个才是重头。那么安装好 pyExcelerator 之后，读了 Readme.txt 之后了解到它的文档正在进行当中，因此想多了解如何使用它需要看它所带的例子，甚至看源程序。下面是我从例子中了解的如何写一个 Excel 文档需要了解的。 </p><p>为了方便，在导入这个模块中使用了import *的方式。 </p><blockquote><p>from pyExcelerator import *</p></blockquote><p>首先导入模块，然后是生成工作薄。 </p><blockquote><p>w = Workbook()</p></blockquote><p>接着是加入一个工作表(sheet)。 </p><blockquote><p>ws = w.add_sheet('Hey, Dude')</p></blockquote><p>然后就可以保存了。 </p><blockquote><p>w.save('mini.xls')</p></blockquote><p>上面的代码加在一起就是： </p><blockquote><p>from pyExcelerator import * </p><p>w = Workbook()<br /> ws = w.add_sheet('Hey, Dude')<br /> w.save('mini.xls')</p></blockquote><p>这就是最小的一个例子了，在例子中叫mini.py。你可以在例子目录下运行mini.py看一看是不是生成了一个空的Excel文件。 </p><p>如果想加入中文很简单，改为： </p><blockquote><p>#coding=cp936<br /> from pyExcelerator import * </p><p>w = Workbook()<br /> ws = w.add_sheet(u'这是中文')<br />w.save('mini.xls')</p></blockquote><p>这样上面的执行结果是生成一个空Excel文件，但它的第一个sheet的名字为&#8220;这是中文&#8221;。就这样，只要保证你写入时使用unicode就行了。 </p><p>空文件可以生成，那么如何插入单元格呢？ </p><blockquote><p>ws.write(i, j, value)</p></blockquote><p>其中value为值，可以是unicode。 </p><p>接着，我们可能想改变单元格的样式，如字体： </p><blockquote><p>font0 = Font()<br /> font0.name = 'Times New Roman'<br /> font0.struck_out = True<br /> font0.bold = True </p><p>style0 = XFStyle()<br /> style0.font = font0</p></blockquote><p>这样我们创建了一个字体，然后又生成了一个样式。注意，<strong>真正起作用的是样式</strong>，字体不过是样式中的一种效果。 </p><p>这样在写入单元格时带着这个样式就行了，还是使用上面的write()方法： </p><blockquote><p>ws.write(1, 1, 'Test', style0)</p></blockquote><p>这是在名为ws的sheet中的第(1,1)单元格写入了值为"Test"的内容，并且它的样式为style0。 </p><p>然后我们还可以设置单元格的边框： </p><blockquote><p>&nbsp;&nbsp;&nbsp; borders = Borders()<br /> &nbsp;&nbsp;&nbsp; borders.left = 5<br /> &nbsp;&nbsp;&nbsp; style.borders = borders</p></blockquote><div class="code">上面创建了一个边框效果，设置了左边框，至于５是什么意思，我也不清楚，随便写的。然后放到样式中。</div><div class="code">上面的例子可以参考format.py程序</div><div class="code"><br /></div><div class="code"><p class="postText">其它还有许多的效果，简单地列一下：</p><table style="width: 400px;" border="1" cellspacing="1" cellpadding="1"><tbody><tr><td>&nbsp;示例名</td><td>说明&nbsp;</td></tr><tr><td>&nbsp;col_width.py</td><td>改变单元格宽度&nbsp;</td></tr><tr><td>&nbsp;row_style.py</td><td>设置行的高度&nbsp;</td></tr><tr><td>&nbsp;merged*.py</td><td><p>单元格合并&nbsp;</p></td></tr><tr><td>&nbsp;image.py</td><td><p>插入图片&nbsp;</p></td></tr><tr><td>&nbsp;outline*.py</td><td><p>大纲效果(以前真没用过)&nbsp;</p></td></tr><tr><td>&nbsp;wsprops.py</td><td><p>sheet的属性值打印&nbsp;</p></td></tr><tr><td>&nbsp;xls2*.py</td><td><p>Excel转为其它的文件格式&nbsp;</p></td></tr></tbody></table><p class="postText">大家有兴趣自已照着例子学吧。</p><p class="postText">&nbsp;</p><p class="postText">&nbsp;</p><p class="postText">&nbsp;</p><p class="postText">四： 时间小示例</p><p class="postText">&nbsp;</p><p class="postText">给俺的boss写的一个小工具，使用Python对Excel进行统计，然后把结束生成一个新的Excel表格，使用到了<a href="http://www.lexicon.net/sjmachin/xlrd.htm" target="_blank">xlrd</a>和<a href="http://sourceforge.net/projects/pyexcelerator/" target="_blank">pyExcelerator</a>两个库。<br /> 简单的介绍一下这两个库，先说xlrd，这个库读Excel比较方便，各种方法使用起来也挺方便：<br />bk = xlrd.open_workbook('your.xls')<br /> sh = bk.sheets()[-1]<br />上面两句就可以打开Excel表格中的一个sheet，sheets得到的是一个list，存放所有的sheet。<br />sh.nrows是该sheet中的行数，知道这个后就可以使用for循环来读所有的单元格了：<br />sh.row(i)[3]这个就代表第i行的第4列。<br /> 再看看pyExcelerator，这个用起来有点别扭：<br />sheets = parse_xls('result.xls')<br />先打开一个表格，sheets是一个list，包含了所有表格的内容，每一项就是一个sheet，而每个sheet是二元tuple，第一个是该sheet的名字，第二个是一个dict，dict的key是一个二元组，表示单元格的坐标，如(0,0)，第一行第一列。<br /> 从上面的分析中可以得出要访问Excel中第一个sheet的第一行第一列元素需要：<br />sheets[0][1][(0,0)]<br /> pyExcelerator也不能得到行列数。<br /> 写文件也比较简单：<br />wb = Workbook()<br /> ws = wb.add_sheet('result')<br /> ws.write(0,0,&#8220;hello&#8221;)<br />wb.save('result.xls')<br />就不解释了:-)<br />写文件时需要注意直接写Unicode内容进去，而不要写编码过的内容。<br /> 给boss的代码：PYTHON: <br /> #!/usr/bin/env python<br /> # -*- coding=utf-8 -*-<br /> #Using GPL v2<br /><br /> import xlrd<br /> from pyExcelerator import *<br /><br /> city = [(u'山城','[2,3]d+'),(u'水国','4d+'),(u'火县','5d+'),<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (u'土城','6d+'),(u'土国','7d+'),(u'火乡','8[1-5]d+'),<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (u'水乡','8[067]d+'),]<br /><br /> fname = '0107CRM.xls'<br /> bk = xlrd.open_workbook(fname)<br /> sh = bk.sheets()[-1]<br /> nrows = sh.nrows<br /> #result中按顺序存放各city中各套餐的数量<br />#顺序为XTa+、XTb、XTb+<br /> result = []<br /> for i in range(len(city)):<br /> &nbsp;&nbsp;&nbsp; result.append([0,0,0])<br /><br /><br /> for r in range(1,nrows):<br /> &nbsp;&nbsp;&nbsp; num = str(sh.row(r)[3])[7:]<br /> &nbsp;&nbsp;&nbsp; flag = False<br /> &nbsp;&nbsp;&nbsp; for i in range(len(city)):<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if re.match(city[i][1],num):<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; flag = True<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if sh.row(r)[2].value == 3001.0:<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name = sh.row(r)[0].value.encode('utf8')<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if 'XTa＋' in name:<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result[i][0]+=1<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if 'XTb' in name and 'XTb＋' not in name:<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result[i][1]+=1<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if 'XTb＋' in name:<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result[i][2]+=1<br /> &nbsp;&nbsp;&nbsp; if not flag:<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print "NO:"+num<br /><br /> print result<br /><br /> titles = [u'局向',u'数',u'M录入数',u'X数',&#8230;&#8230;&#8230;&#8230;]<br />wb = Workbook()<br /> ws = wb.add_sheet('result')<br /> for i in range(len(titles)):<br /> &nbsp;&nbsp;&nbsp; ws.write(0,i,titles[i])<br /><br /><span style="color: rgb(0, 0, 255);">for i in range(len(city)):<br /> &nbsp;&nbsp;&nbsp; ws.write(i+1,0,city[i][0])<br /> &nbsp;&nbsp;&nbsp; ws.write(i+1,1,result[i][0])<br /> &nbsp;&nbsp;&nbsp; ws.write(i+1,4,result[i][1])<br /> &nbsp;&nbsp;&nbsp; ws.write(i+1,7,result[i][2])<br /> &nbsp;&nbsp;&nbsp; ws.write(i+1,10,result[i][0]+result[i][1]+result[i][2])<br /> ws.write(i+2,1,"=SUM(B2:B8)")<br /> wb.save('result.xls')</span></p><p class="postText"><br /></p><p class="postText"><span style="color: rgb(51, 51, 51);"><strong>后记:</strong></span></p><p class="postText">python对excel的操作确实不太强大，目前为止我只用过pyExcelerator，还有一个xlrd-xlwt的plugin；貌似这几个对日常简单的excel操作就够用了！</p><p class="postText">最近回头看这篇blog的阅读量还是挺大，今天工作之余写下此后记，希望能和各位python高手们交流，共同提高！</p><p class="postText"><br /></p><p class="postText">excel相关文章：<br /></p><p class="postText">1.xlrd-xlwt模块&nbsp; <span class="link_title"><a title="xlrd读取excel文件(基本功能)" href="http://blog.csdn.net/suofiya2008/article/details/5587386">xlrd读取excel文件(基本功能)</a></span> <br /></p><p class="postText">2. 我同事鱿鱼哥解决excel2007读写的文章<span class="link_title"><a title="openpyxl 读写excel2007使用笔记【感谢鱿鱼哥】" href="http://blog.csdn.net/suofiya2008/article/details/6284208"> openpyxl 读写excel2007使用笔记【感谢鱿鱼哥】</a></span></p></div></div></div><img src ="http://www.blogjava.net/pts/aggbug/420390.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/pts/" target="_blank">pts</a> 2014-11-21 09:35 <a href="http://www.blogjava.net/pts/archive/2014/11/21/420390.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>PYTHON与EXCEL：openpyxl 读写excel2007</title><link>http://www.blogjava.net/pts/archive/2014/11/21/420389.html</link><dc:creator>pts</dc:creator><author>pts</author><pubDate>Fri, 21 Nov 2014 01:34:00 GMT</pubDate><guid>http://www.blogjava.net/pts/archive/2014/11/21/420389.html</guid><wfw:comment>http://www.blogjava.net/pts/comments/420389.html</wfw:comment><comments>http://www.blogjava.net/pts/archive/2014/11/21/420389.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/pts/comments/commentRss/420389.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/pts/services/trackbacks/420389.html</trackback:ping><description><![CDATA[<p>【FROM】</p><p><a href="http://blog.csdn.net/suofiya2008/article/details/6284208">http://blog.csdn.net/suofiya2008/article/details/6284208</a><br /><br />有一万年没来这儿写blog了，今天等着发版，抽空来写点东西吧。</p><p>python有很多模块都是用来操作excel的，比如xlrd，xlwt，pyExcelerator。用着很方便，但是问题是，只能支持到 excel2003。虽然一般的应用其实足够了，但是如果遇到了导出大量数据（超过65535条）的需求时，excel2003就不够用了。所以我就只好 去找一个能支持excel2007的模块。</p><p>google了一下，发现了这个openpyxl，不过网上也没什么中文的文档可以看，于是就自己琢磨琢磨。</p><p>I.安装</p><p>openpyxl的最新版本是1.5.0 下载地址 <a href="http://pypi.python.org/pypi/openpyxl/1.5.0">http://pypi.python.org/pypi/openpyxl/1.5.0</a> </p><p>需求python的版本是2.6+&nbsp;&nbsp;，也就是说，如果centOS系统的机器想用，那得升级系统的python。。。</p><p>安装就是解压缩，然后cd到目录，然后</p><p><span style="color: rgb(255, 0, 0);">python setup.py install</span> </p><p><span style="color: rgb(0, 0, 0);">你懂的~</span> </p><p>&nbsp;II.读取excel2007文件</p><div class="dp-highlighter"><div class="bar"><div class="tools"><a href="http://blog.csdn.net/hxsyewlink/archive/2011/03/21/6265790.aspx"><u><font color="#0066cc">view plain</font></u></a> <a href="http://blog.csdn.net/hxsyewlink/archive/2011/03/21/6265790.aspx"><u><font color="#0066cc">copy to clipboard</font></u></a> <a href="http://blog.csdn.net/hxsyewlink/archive/2011/03/21/6265790.aspx"><u><font color="#0066cc">print</font></u></a> <a href="http://blog.csdn.net/hxsyewlink/archive/2011/03/21/6265790.aspx"><u><font color="#0066cc">?</font></u></a> </div></div><ol class="dp-py"><li class="alt"><span class="comment">#-*-&nbsp;coding:utf-8&nbsp;-*</span> <span>&nbsp;&nbsp;</span>  </li><li><span>&nbsp;&nbsp;</span> </li><li class="alt"><span class="keyword">from</span> <span>&nbsp;openpyxl.reader.excel&nbsp;</span> <span class="keyword">import</span> <span>&nbsp;load_workbook&nbsp;&nbsp;</span>  </li><li><span class="keyword">import</span> <span>&nbsp;MySQLdb&nbsp;&nbsp;</span>  </li><li class="alt"><span class="keyword">import</span> <span>&nbsp;time&nbsp;&nbsp;</span>  </li><li><span>&nbsp;&nbsp;</span> </li><li class="alt"><span class="comment">#开始时间</span> <span>&nbsp;&nbsp;</span>  </li><li><span>startTime&nbsp;=&nbsp;time.time()&nbsp;&nbsp;</span> </li><li class="alt"><span>&nbsp;&nbsp;</span> </li><li><span class="comment">#读取excel2007文件</span> <span>&nbsp;&nbsp;</span>  </li><li class="alt"><span>wb&nbsp;=&nbsp;load_workbook(filename&nbsp;=&nbsp;r<span class="string">'empty_book.xlsx'</span> <span>)&nbsp;&nbsp;</span> </span> </li><li><span>&nbsp;&nbsp;</span> </li><li class="alt"><span class="comment">#显示有多少张表</span> <span>&nbsp;&nbsp;</span>  </li><li><span class="keyword">print</span> <span>&nbsp;</span> <span class="string">"Worksheet&nbsp;range(s):"</span> <span>,&nbsp;wb.get_named_ranges()&nbsp;&nbsp;</span>  </li><li class="alt"><span class="keyword">print</span> <span>&nbsp;</span> <span class="string">"Worksheet&nbsp;name(s):"</span> <span>,&nbsp;wb.get_sheet_names()&nbsp;&nbsp;</span>  </li><li><span>&nbsp;&nbsp;</span> </li><li class="alt"><span class="comment">#取第一张表</span> <span>&nbsp;&nbsp;</span>  </li><li><span>sheetnames&nbsp;=&nbsp;wb.get_sheet_names()&nbsp;&nbsp;</span> </li><li class="alt"><span>ws&nbsp;=&nbsp;wb.get_sheet_by_name(sheetnames[<span class="number">0</span> <span>])&nbsp;&nbsp;</span> </span> </li><li><span>&nbsp;&nbsp;</span> </li><li class="alt"><span class="comment">#显示表名，表行数，表列数</span> <span>&nbsp;&nbsp;</span>  </li><li><span class="keyword">print</span> <span>&nbsp;</span> <span class="string">"Work&nbsp;Sheet&nbsp;Titile:"</span> <span>,ws.title&nbsp;&nbsp;</span>  </li><li class="alt"><span class="keyword">print</span> <span>&nbsp;</span> <span class="string">"Work&nbsp;Sheet&nbsp;Rows:"</span> <span>,ws.get_highest_row()&nbsp;&nbsp;</span>  </li><li><span class="keyword">print</span> <span>&nbsp;</span> <span class="string">"Work&nbsp;Sheet&nbsp;Cols:"</span> <span>,ws.get_highest_column()&nbsp;&nbsp;</span>  </li><li class="alt"><span>&nbsp;&nbsp;</span> </li><li><span>&nbsp;&nbsp;</span> </li><li class="alt"><span class="comment">#&nbsp;建立存储数据的字典&nbsp;</span> <span>&nbsp;&nbsp;</span>  </li><li><span>data_dic&nbsp;=&nbsp;{}&nbsp;&nbsp;&nbsp;</span> </li><li class="alt"><span>&nbsp;&nbsp;</span> </li><li><span class="comment">#把数据存到字典中</span> <span>&nbsp;&nbsp;</span>  </li><li class="alt"><span class="keyword">for</span> <span>&nbsp;rx&nbsp;</span> <span class="keyword">in</span> <span>&nbsp;range(ws.get_highest_row()):&nbsp;&nbsp;</span>  </li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span> </li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;temp_list&nbsp;=&nbsp;[]&nbsp;&nbsp;</span> </li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;pid&nbsp;=&nbsp;ws.cell(row&nbsp;=&nbsp;rx,column&nbsp;=&nbsp;<span class="number">0</span> <span>).value&nbsp;&nbsp;</span> </span> </li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;w1&nbsp;=&nbsp;ws.cell(row&nbsp;=&nbsp;rx,column&nbsp;=&nbsp;<span class="number">1</span> <span>).value&nbsp;&nbsp;</span> </span> </li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;w2&nbsp;=&nbsp;ws.cell(row&nbsp;=&nbsp;rx,column&nbsp;=&nbsp;<span class="number">2</span> <span>).value&nbsp;&nbsp;</span> </span> </li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;w3&nbsp;=&nbsp;ws.cell(row&nbsp;=&nbsp;rx,column&nbsp;=&nbsp;<span class="number">3</span> <span>).value&nbsp;&nbsp;</span> </span> </li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;w4&nbsp;=&nbsp;ws.cell(row&nbsp;=&nbsp;rx,column&nbsp;=&nbsp;<span class="number">4</span> <span>).value&nbsp;&nbsp;</span> </span> </li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;temp_list&nbsp;=&nbsp;[w1,w2,w3,w4]&nbsp;&nbsp;</span> </li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span> </li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;data_dic[pid]&nbsp;=&nbsp;temp_list&nbsp;&nbsp;</span> </li><li><span>&nbsp;&nbsp;</span> </li><li class="alt"><span class="comment">#打印字典数据个数</span> <span>&nbsp;&nbsp;</span>  </li><li><span class="keyword">print</span> <span>&nbsp;</span> <span class="string">'Total:%d'</span> <span>&nbsp;%len(data_dic)&nbsp;&nbsp;</span>  </li></ol></div><p><div class="dp-highlighter bg_python"><div class="bar"><div class="tools"><strong>[python]</strong> <a title="view plain" class="ViewSource" href="http://blog.csdn.net/suofiya2008/article/details/6284208#"><u><font color="#0066cc">view plain</font></u></a><a title="copy" class="CopyToClipboard" href="http://blog.csdn.net/suofiya2008/article/details/6284208#"><u><font color="#0066cc">copy</font></u></a><a title="print" class="PrintSource" href="http://blog.csdn.net/suofiya2008/article/details/6284208#"><u><font color="#0066cc">print</font></u></a><a title="?" class="About" href="http://blog.csdn.net/suofiya2008/article/details/6284208#"><u><font color="#0066cc">?</font></u></a></div></div><ol class="dp-py"><li class="alt"><span class="comment">#-*-&nbsp;coding:utf-8&nbsp;-*</span><span>&nbsp;&nbsp;</span></li><li><span class="keyword">from</span><span>&nbsp;openpyxl.reader.excel&nbsp;</span><span class="keyword">import</span><span>&nbsp;load_workbook&nbsp;&nbsp;</span></li><li class="alt"><span class="keyword">import</span><span>&nbsp;MySQLdb&nbsp;&nbsp;</span></li><li><span class="keyword">import</span><span>&nbsp;time&nbsp;&nbsp;</span></li><li class="alt"><span class="comment">#开始时间</span><span>&nbsp;&nbsp;</span></li><li><span>startTime&nbsp;=&nbsp;time.time()&nbsp;&nbsp;</span></li><li class="alt"><span class="comment">#读取excel2007文件</span><span>&nbsp;&nbsp;</span></li><li><span>wb&nbsp;=&nbsp;load_workbook(filename&nbsp;=&nbsp;r<span class="string">'empty_book.xlsx'</span><span>)&nbsp;&nbsp;</span></span></li><li class="alt"><span class="comment">#显示有多少张表</span><span>&nbsp;&nbsp;</span></li><li><span class="keyword">print</span><span>&nbsp;</span><span class="string">"Worksheet&nbsp;range(s):"</span><span>,&nbsp;wb.get_named_ranges()&nbsp;&nbsp;</span></li><li class="alt"><span class="keyword">print</span><span>&nbsp;</span><span class="string">"Worksheet&nbsp;name(s):"</span><span>,&nbsp;wb.get_sheet_names()&nbsp;&nbsp;</span></li><li><span class="comment">#取第一张表</span><span>&nbsp;&nbsp;</span></li><li class="alt"><span>sheetnames&nbsp;=&nbsp;wb.get_sheet_names()&nbsp;&nbsp;</span></li><li><span>ws&nbsp;=&nbsp;wb.get_sheet_by_name(sheetnames[<span class="number">0</span><span>])&nbsp;&nbsp;</span></span></li><li class="alt"><span class="comment">#显示表名，表行数，表列数</span><span>&nbsp;&nbsp;</span></li><li><span class="keyword">print</span><span>&nbsp;</span><span class="string">"Work&nbsp;Sheet&nbsp;Titile:"</span><span>,ws.title&nbsp;&nbsp;</span></li><li class="alt"><span class="keyword">print</span><span>&nbsp;</span><span class="string">"Work&nbsp;Sheet&nbsp;Rows:"</span><span>,ws.get_highest_row()&nbsp;&nbsp;</span></li><li><span class="keyword">print</span><span>&nbsp;</span><span class="string">"Work&nbsp;Sheet&nbsp;Cols:"</span><span>,ws.get_highest_column()&nbsp;&nbsp;</span></li><li class="alt"><span class="comment">#&nbsp;建立存储数据的字典&nbsp;</span><span>&nbsp;&nbsp;</span></li><li><span>data_dic&nbsp;=&nbsp;{}&nbsp;&nbsp;&nbsp;</span></li><li class="alt"><span class="comment">#把数据存到字典中</span><span>&nbsp;&nbsp;</span></li><li><span class="keyword">for</span><span>&nbsp;rx&nbsp;</span><span class="keyword">in</span><span>&nbsp;range(ws.get_highest_row()):&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;temp_list&nbsp;=&nbsp;[]&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;pid&nbsp;=&nbsp;ws.cell(row&nbsp;=&nbsp;rx,column&nbsp;=&nbsp;<span class="number">0</span><span>).value&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;w1&nbsp;=&nbsp;ws.cell(row&nbsp;=&nbsp;rx,column&nbsp;=&nbsp;<span class="number">1</span><span>).value&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;w2&nbsp;=&nbsp;ws.cell(row&nbsp;=&nbsp;rx,column&nbsp;=&nbsp;<span class="number">2</span><span>).value&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;w3&nbsp;=&nbsp;ws.cell(row&nbsp;=&nbsp;rx,column&nbsp;=&nbsp;<span class="number">3</span><span>).value&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;w4&nbsp;=&nbsp;ws.cell(row&nbsp;=&nbsp;rx,column&nbsp;=&nbsp;<span class="number">4</span><span>).value&nbsp;&nbsp;</span></span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;temp_list&nbsp;=&nbsp;[w1,w2,w3,w4]&nbsp;&nbsp;</span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;data_dic[pid]&nbsp;=&nbsp;temp_list&nbsp;&nbsp;</span></li><li class="alt"><span class="comment">#打印字典数据个数</span><span>&nbsp;&nbsp;</span></li><li><span class="keyword">print</span><span>&nbsp;</span><span class="string">'Total:%d'</span><span>&nbsp;%len(data_dic)&nbsp;&nbsp;</span></li></ol></div><textarea name="code" class="python" style="display: none;" rows="15" cols="50">#-*- coding:utf-8 -*
from openpyxl.reader.excel import load_workbook
import MySQLdb
import time
#开始时间
startTime = time.time()
#读取excel2007文件
wb = load_workbook(filename = r'empty_book.xlsx')
#显示有多少张表
print "Worksheet range(s):", wb.get_named_ranges()
print "Worksheet name(s):", wb.get_sheet_names()
#取第一张表
sheetnames = wb.get_sheet_names()
ws = wb.get_sheet_by_name(sheetnames[0])
#显示表名，表行数，表列数
print "Work Sheet Titile:",ws.title
print "Work Sheet Rows:",ws.get_highest_row()
print "Work Sheet Cols:",ws.get_highest_column()
# 建立存储数据的字典 
data_dic = {} 
#把数据存到字典中
for rx in range(ws.get_highest_row()):
    
    temp_list = []
    pid = ws.cell(row = rx,column = 0).value
    w1 = ws.cell(row = rx,column = 1).value
    w2 = ws.cell(row = rx,column = 2).value
    w3 = ws.cell(row = rx,column = 3).value
    w4 = ws.cell(row = rx,column = 4).value
    temp_list = [w1,w2,w3,w4]
   
    data_dic[pid] = temp_list
#打印字典数据个数
print 'Total:%d' %len(data_dic)</textarea><p>&nbsp;</p>&nbsp;&nbsp;&nbsp; <p>&nbsp;注意的是ws.cell()方法，支持的参数有两种，<span style="font-family: Courier New;">cell（</span> <em>coordinate=None</em> , <em>row=None</em> , <em>column=None）</em> </p><p><em></em> </p><p>coordinate坐标，eg&nbsp; ws.cell("B1") </p><p>row 和 column 是行和列 ，都是从0开始</p><p>还有，如果想取得格里的值，得用ws.cell("A1").value 取到，如果用过xlrd，因为写法差不多，可能就会忘记加value了。</p><p>III.写入excel2007</p><p>&nbsp;</p><div class="dp-highlighter"><div class="bar"><div class="tools"><a href="http://blog.csdn.net/hxsyewlink/archive/2011/03/21/6265790.aspx"><u><font color="#0066cc">view plain</font></u></a> <a href="http://blog.csdn.net/hxsyewlink/archive/2011/03/21/6265790.aspx"><u><font color="#0066cc">copy to clipboard</font></u></a> <a href="http://blog.csdn.net/hxsyewlink/archive/2011/03/21/6265790.aspx"><u><font color="#0066cc">print</font></u></a> <a href="http://blog.csdn.net/hxsyewlink/archive/2011/03/21/6265790.aspx"><u><font color="#0066cc">?</font></u></a> </div></div><ol class="dp-py"><li class="alt"><span>写excel2007&nbsp;&nbsp;</span>  </li><li><span>&nbsp;&nbsp;</span> </li><li class="alt"><span class="comment">#-*-&nbsp;coding:utf-8&nbsp;-*</span> <span>&nbsp;&nbsp;</span>  </li><li><span>&nbsp;&nbsp;</span> </li><li class="alt"><span>&nbsp;&nbsp;</span> </li><li><span class="keyword">import</span> <span>&nbsp;MySQLdb&nbsp;&nbsp;</span>  </li><li class="alt"><span class="keyword">import</span> <span>&nbsp;time&nbsp;&nbsp;</span>  </li><li><span class="keyword">import</span> <span>&nbsp;sys&nbsp;&nbsp;</span>  </li><li class="alt"><span class="comment">#workbook相关</span> <span>&nbsp;&nbsp;</span>  </li><li><span class="keyword">from</span> <span>&nbsp;openpyxl.workbook&nbsp;</span> <span class="keyword">import</span> <span>&nbsp;Workbook&nbsp;&nbsp;</span>  </li><li class="alt"><span class="comment">#万恶的ExcelWriter，妹的封装好了不早说，封装了很强大的excel写的功能</span> <span>&nbsp;&nbsp;</span>  </li><li><span class="keyword">from</span> <span>&nbsp;openpyxl.writer.excel&nbsp;</span> <span class="keyword">import</span> <span>&nbsp;ExcelWriter&nbsp;&nbsp;</span>  </li><li class="alt"><span class="comment">#一个eggache的数字转为列字母的方法</span> <span>&nbsp;&nbsp;</span>  </li><li><span class="keyword">from</span> <span>&nbsp;openpyxl.cell&nbsp;</span> <span class="keyword">import</span> <span>&nbsp;get_column_letter&nbsp;&nbsp;</span>  </li><li class="alt"><span>&nbsp;&nbsp;</span> </li><li><span>&nbsp;&nbsp;</span> </li><li class="alt"><span class="comment">#新建一个workbook</span> <span>&nbsp;&nbsp;</span>  </li><li><span>&nbsp;&nbsp;</span> </li><li class="alt"><span>wb&nbsp;=&nbsp;Workbook()&nbsp;&nbsp;</span> </li><li><span class="comment">#新建一个excelWriter</span> <span>&nbsp;&nbsp;</span>  </li><li class="alt"><span>ew&nbsp;=&nbsp;ExcelWriter(workbook&nbsp;=&nbsp;wb)&nbsp;&nbsp;</span> </li><li><span>&nbsp;&nbsp;</span> </li><li class="alt"><span class="comment">#设置文件输出路径与名称</span> <span>&nbsp;&nbsp;</span>  </li><li><span>dest_filename&nbsp;=&nbsp;r<span class="string">'empty_book.xlsx'</span> <span>&nbsp;&nbsp;</span> </span> </li><li class="alt"><span>&nbsp;&nbsp;</span> </li><li><span class="comment">#第一个sheet是ws</span> <span>&nbsp;&nbsp;</span>  </li><li class="alt"><span>ws&nbsp;=&nbsp;wb.worksheets[<span class="number">0</span> <span>]&nbsp;&nbsp;</span> </span> </li><li><span>&nbsp;&nbsp;</span> </li><li class="alt"><span class="comment">#设置ws的名称</span> <span>&nbsp;&nbsp;</span>  </li><li><span>ws.title&nbsp;=&nbsp;<span class="string">"range&nbsp;names"</span> <span>&nbsp;&nbsp;&nbsp;</span> </span> </li><li class="alt"><span>&nbsp;&nbsp;</span> </li><li><span>&nbsp;&nbsp;</span> </li><li class="alt"><span class="comment">#录入数据，注意col是数字转字母，然后需要限定%s（string型）当参数传到ws.cell()方法中去,records可以想象为一个从数据库里查询出来的数据集合</span> <span>&nbsp;&nbsp;</span>  </li><li><span>i=<span class="number">1</span> <span>&nbsp;&nbsp;</span> </span> </li><li class="alt"><span>table&nbsp;=&nbsp;{}&nbsp;&nbsp;</span> </li><li><span class="keyword">for</span> <span>&nbsp;record&nbsp;</span> <span class="keyword">in</span> <span>&nbsp;records:&nbsp;&nbsp;</span>  </li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">for</span> <span>&nbsp;x&nbsp;</span> <span class="keyword">in</span> <span>&nbsp;range(</span> <span class="number">1</span> <span>,len(record)+</span> <span class="number">1</span> <span>):&nbsp;&nbsp;</span> </span> </li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;col&nbsp;=&nbsp;get_column_letter(x)&nbsp;&nbsp;</span> </li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ws.cell(<span class="string">'%s%s'</span> <span>%(col,&nbsp;i)).value&nbsp;=&nbsp;</span> <span class="string">'%s'</span> <span>&nbsp;%&nbsp;(record[x-</span> <span class="number">1</span> <span>])&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span> </span> </li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span> </li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;i+=<span class="number">1</span> <span>&nbsp;&nbsp;</span> </span> </li><li><span>&nbsp;&nbsp;</span> </li><li class="alt"><span class="comment">#又建了一个sheet，ws名字都没变，太省了。。。但是确实是一个新的sheet，不会影响之前那个sheet的东西</span> <span>&nbsp;&nbsp;</span>  </li><li><span>ws&nbsp;=&nbsp;wb.create_sheet()&nbsp;&nbsp;</span> </li><li class="alt"><span>&nbsp;&nbsp;</span> </li><li><span>ws.title&nbsp;=&nbsp;<span class="string">'Pi'</span> <span>&nbsp;&nbsp;</span> </span> </li><li class="alt"><span>&nbsp;&nbsp;</span> </li><li><span>ws.cell(<span class="string">'F5'</span> <span>).value&nbsp;=&nbsp;</span> <span class="number">3.14</span> <span>&nbsp;&nbsp;</span> </span> </li><li class="alt"><span>&nbsp;&nbsp;</span> </li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span> </li><li class="alt"><span class="comment">#写文件</span> <span>&nbsp;&nbsp;</span>  </li><li><span>ew.save(filename&nbsp;=&nbsp;dest_filename)&nbsp;&nbsp;</span> </li></ol></div><p><div class="dp-highlighter bg_python"><div class="bar"><div class="tools"><strong>[python]</strong> <a title="view plain" class="ViewSource" href="http://blog.csdn.net/suofiya2008/article/details/6284208#"><u><font color="#0066cc">view plain</font></u></a><a title="copy" class="CopyToClipboard" href="http://blog.csdn.net/suofiya2008/article/details/6284208#"><u><font color="#0066cc">copy</font></u></a><a title="print" class="PrintSource" href="http://blog.csdn.net/suofiya2008/article/details/6284208#"><u><font color="#0066cc">print</font></u></a><a title="?" class="About" href="http://blog.csdn.net/suofiya2008/article/details/6284208#"><u><font color="#0066cc">?</font></u></a></div></div><ol class="dp-py"><li class="alt"><span>写excel2007&nbsp;&nbsp;</span></li><li><span class="comment">#-*-&nbsp;coding:utf-8&nbsp;-*</span><span>&nbsp;&nbsp;</span></li><li class="alt"><span class="keyword">import</span><span>&nbsp;MySQLdb&nbsp;&nbsp;</span></li><li><span class="keyword">import</span><span>&nbsp;time&nbsp;&nbsp;</span></li><li class="alt"><span class="keyword">import</span><span>&nbsp;sys&nbsp;&nbsp;</span></li><li><span class="comment">#workbook相关</span><span>&nbsp;&nbsp;</span></li><li class="alt"><span class="keyword">from</span><span>&nbsp;openpyxl.workbook&nbsp;</span><span class="keyword">import</span><span>&nbsp;Workbook&nbsp;&nbsp;</span></li><li><span class="comment">#万恶的ExcelWriter，妹的封装好了不早说，封装了很强大的excel写的功能</span><span>&nbsp;&nbsp;</span></li><li class="alt"><span class="keyword">from</span><span>&nbsp;openpyxl.writer.excel&nbsp;</span><span class="keyword">import</span><span>&nbsp;ExcelWriter&nbsp;&nbsp;</span></li><li><span class="comment">#一个eggache的数字转为列字母的方法</span><span>&nbsp;&nbsp;</span></li><li class="alt"><span class="keyword">from</span><span>&nbsp;openpyxl.cell&nbsp;</span><span class="keyword">import</span><span>&nbsp;get_column_letter&nbsp;&nbsp;</span></li><li><span class="comment">#新建一个workbook</span><span>&nbsp;&nbsp;</span></li><li class="alt"><span>wb&nbsp;=&nbsp;Workbook()&nbsp;&nbsp;</span></li><li><span class="comment">#新建一个excelWriter</span><span>&nbsp;&nbsp;</span></li><li class="alt"><span>ew&nbsp;=&nbsp;ExcelWriter(workbook&nbsp;=&nbsp;wb)&nbsp;&nbsp;</span></li><li><span class="comment">#设置文件输出路径与名称</span><span>&nbsp;&nbsp;</span></li><li class="alt"><span>dest_filename&nbsp;=&nbsp;r<span class="string">'empty_book.xlsx'</span><span>&nbsp;&nbsp;</span></span></li><li><span class="comment">#第一个sheet是ws</span><span>&nbsp;&nbsp;</span></li><li class="alt"><span>ws&nbsp;=&nbsp;wb.worksheets[<span class="number">0</span><span>]&nbsp;&nbsp;</span></span></li><li><span class="comment">#设置ws的名称</span><span>&nbsp;&nbsp;</span></li><li class="alt"><span>ws.title&nbsp;=&nbsp;<span class="string">"range&nbsp;names"</span><span>&nbsp;&nbsp;&nbsp;</span></span></li><li><span class="comment">#录入数据，注意col是数字转字母，然后需要限定%s（string型）当参数传到ws.cell()方法中去,records可以想象为一个从数据库里查询出来的数据集合</span><span>&nbsp;&nbsp;</span></li><li class="alt"><span>i=<span class="number">1</span><span>&nbsp;&nbsp;</span></span></li><li><span>table&nbsp;=&nbsp;{}&nbsp;&nbsp;</span></li><li class="alt"><span class="keyword">for</span><span>&nbsp;record&nbsp;</span><span class="keyword">in</span><span>&nbsp;records:&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">for</span><span>&nbsp;x&nbsp;</span><span class="keyword">in</span><span>&nbsp;range(</span><span class="number">1</span><span>,len(record)+</span><span class="number">1</span><span>):&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;col&nbsp;=&nbsp;get_column_letter(x)&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ws.cell(<span class="string">'%s%s'</span><span>%(col,&nbsp;i)).value&nbsp;=&nbsp;</span><span class="string">'%s'</span><span>&nbsp;%&nbsp;(record[x-</span><span class="number">1</span><span>])&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li><li><span>&nbsp;&nbsp;&nbsp;&nbsp;i+=<span class="number">1</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span class="comment">#又建了一个sheet，ws名字都没变，太省了。。。但是确实是一个新的sheet，不会影响之前那个sheet的东西</span><span>&nbsp;&nbsp;</span></li><li><span>ws&nbsp;=&nbsp;wb.create_sheet()&nbsp;&nbsp;</span></li><li class="alt"><span>ws.title&nbsp;=&nbsp;<span class="string">'Pi'</span><span>&nbsp;&nbsp;</span></span></li><li><span>ws.cell(<span class="string">'F5'</span><span>).value&nbsp;=&nbsp;</span><span class="number">3.14</span><span>&nbsp;&nbsp;</span></span></li><li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li><li><span class="comment">#写文件</span><span>&nbsp;&nbsp;</span></li><li class="alt"><span>ew.save(filename&nbsp;=&nbsp;dest_filename)&nbsp;&nbsp;</span></li></ol></div><textarea name="code" class="python" style="display: none;" rows="15" cols="81">写excel2007
#-*- coding:utf-8 -*
import MySQLdb
import time
import sys
#workbook相关
from openpyxl.workbook import Workbook
#万恶的ExcelWriter，妹的封装好了不早说，封装了很强大的excel写的功能
from openpyxl.writer.excel import ExcelWriter
#一个eggache的数字转为列字母的方法
from openpyxl.cell import get_column_letter
#新建一个workbook
wb = Workbook()
#新建一个excelWriter
ew = ExcelWriter(workbook = wb)
#设置文件输出路径与名称
dest_filename = r'empty_book.xlsx'
#第一个sheet是ws
ws = wb.worksheets[0]
#设置ws的名称
ws.title = "range names" 
#录入数据，注意col是数字转字母，然后需要限定%s（string型）当参数传到ws.cell()方法中去,records可以想象为一个从数据库里查询出来的数据集合
i=1
table = {}
for record in records:
    for x in range(1,len(record)+1):
        col = get_column_letter(x)
        ws.cell('%s%s'%(col, i)).value = '%s' % (record[x-1])      
            
    i+=1
#又建了一个sheet，ws名字都没变，太省了。。。但是确实是一个新的sheet，不会影响之前那个sheet的东西
ws = wb.create_sheet()
ws.title = 'Pi'
ws.cell('F5').value = 3.14
    
#写文件
ew.save(filename = dest_filename)
</textarea><p>&nbsp;</p><p>&nbsp;注意的地方：</p><p># col是用列号x为参数，调用了这个模块的<span style="color: rgb(255, 0, 0);">get_column_letter<span style="color: rgb(0, 0, 0);">方法算出来的字母，这个比较蛋疼。</span> </span> </p><p style="margin: 0in; font-family: 微软雅黑; font-size: 10pt;"><span>&nbsp; </span> <span style="color: red;"><span>&nbsp;</span> col = get_column_letter(x) </span> </p><p style="margin: 0in; font-family: 微软雅黑; font-size: 10pt;">&nbsp;</p><p style="margin: 0in; font-family: 微软雅黑; font-size: 10pt;"><span style="color: rgb(0, 0, 0);">#在为数据格赋值的时候，注意写的格式：要不会有各种不靠谱的问题出现（这个是用坐标的方式写的，其实用row ，col的方式可能没那么麻烦）</span> </p><p style="margin: 0in; font-family: 微软雅黑;"><span style="font-size: 10pt;"><span>&nbsp;</span> </span> <span style="color: rgb(51, 102, 255); font-size: 10pt;"><span>&nbsp;</span> </span> <span style="color: rgb(51, 102, 255); font-size: 18pt;">ws.cell(</span> <span style="color: red; font-size: 18pt;">'%s%s'%(col, i)</span> <span style="color: rgb(51, 102, 255); font-size: 18pt;">).value = </span> <span style="color: red; font-size: 18pt;">'%s' % (record[x-1])</span> <span style="color: rgb(51, 102, 255); font-size: 18pt;"></span> </p><p>关于该模块的API&nbsp; 可以查询官方文档&nbsp;<span lang="en-US" style="font-family: Calibri;"><span>&nbsp;</span> </span> <a href="http://packages.python.org/openpyxl/api.html"><span lang="zh-CN" style="font-family: 微软雅黑;">http://packages.python.org/openpyxl/api.html</span> </a> </p><p>总体来说，这个模块还是挺方便的，但是问题就是在对于python的版本有一定要求，如果在centOs上用，可能会有些问题。</p><p>本文只是简单的写了下使用的方法，之后格式超链接神马的之后再填上~</p><img src ="http://www.blogjava.net/pts/aggbug/420389.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/pts/" target="_blank">pts</a> 2014-11-21 09:34 <a href="http://www.blogjava.net/pts/archive/2014/11/21/420389.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title> [转]Python GUI开发环境的搭建</title><link>http://www.blogjava.net/pts/archive/2014/07/30/416370.html</link><dc:creator>pts</dc:creator><author>pts</author><pubDate>Wed, 30 Jul 2014 08:38:00 GMT</pubDate><guid>http://www.blogjava.net/pts/archive/2014/07/30/416370.html</guid><wfw:comment>http://www.blogjava.net/pts/comments/416370.html</wfw:comment><comments>http://www.blogjava.net/pts/archive/2014/07/30/416370.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/pts/comments/commentRss/416370.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/pts/services/trackbacks/416370.html</trackback:ping><description><![CDATA[<p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;">From：<span style="font-family: verdana, 'courier new'; line-height: 21px;">http://blog.csdn.net/zhangxinrun/article/category/1134723</span></p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;">转载：http://www.cnblogs.com/sding/archive/2011/11/12/2246675.html</p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"><br /></p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"></p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;">最近对Python的开发又来了兴趣，对于Python的开发一直停留在一个表面层的认识，玩的部分比较大。</p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;">Python的入手简单，语法让人爱不释手，在网络通信方面自带有成熟的类库，还有第三方开发的开源包。</p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;">在GUI的开发上，Python自身带有TKinter库，还有第三方的库 (比如wxPython, Qt)</p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;">&nbsp;</p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;">今天就来简单介绍下wxPython开发的环境搭建与示例</p><hr style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;" /><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;">&nbsp;</p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;">开发环境搭建采用<em>wxFormBuilder + uiPad + wxPython，</em>按照顺序进行安装</p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;">Python 2.6 下载地址：<span style="color: #3366ff;"><a href="http://www.python.org/download/releases/2.6.7/" style="color: #336699; text-decoration: none;"><span style="color: #3366ff;">http://www.python.org/download/releases/2.6.7/</span></a></span></p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;">wxPython 2.8&nbsp;下载地址：<span style="color: #3366ff;"><a href="http://www.wxpython.org/download.php#stable" style="color: #336699; text-decoration: none;"><span style="color: #3366ff;">http://www.wxpython.org/download.php#stable</span></a></span></p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;">wxFormBuilder 3.2 beta 下载地址：<span style="color: #3366ff;"><a href="http://sourceforge.net/projects/wxformbuilder/" style="color: #336699; text-decoration: none;"><span style="color: #3366ff;">http://sourceforge.net/projects/wxformbuilder/</span></a></span></p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;">uiPad 4.0 下载地址：<span style="color: #3366ff;"><a href="http://www.onlinedown.net/soft/101104.htm" style="color: #336699; text-decoration: none;"><span style="color: #3366ff;">http://www.onlinedown.net/soft/101104.htm</span></a></span></p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"><span style="color: #3366ff;"><br /></span></p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"><em><strong><span style="font-size: 16px; color: #000000;">Python GUI程式的开发步骤</span></strong></em></p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;">&nbsp;</p><hr style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;" /><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"><strong><span style="font-size: 16px;">1 &nbsp;wxFormBuilder 的界面设计过程</span></strong></p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;">这里不再详述，可以BAIDU下wxPython的界面设计方法</p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"><img alt="" src="http://pic002.cnblogs.com/images/2011/163390/2011111219044855.jpg" style="border: none; max-width: 100%;" /></p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;">&nbsp;</p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"><strong><span style="font-size: 16px;">2 界面设计完成后，接下来对界面上的BUTTON事件进行响应</span></strong></p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;">如下图所示，产生响应事件代码</p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"><img alt="" src="http://pic002.cnblogs.com/images/2011/163390/2011111219113119.png" style="border: none; max-width: 100%;" /></p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;">&nbsp;</p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"><img alt="" src="http://pic002.cnblogs.com/images/2011/163390/2011111219123494.png" style="border: none; max-width: 100%;" /></p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;">&nbsp;</p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"><strong><span style="font-size: 16px;">3 事件映射结束后，复制Python 代码到py文件</span></strong></p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"><img alt="" src="http://pic002.cnblogs.com/images/2011/163390/2011111219143590.png" style="border: none; max-width: 100%;" /></p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;">&nbsp;</p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"><strong><span style="font-size: 16px;">4 用UliPad编辑Py文件</span></strong></p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;">在py文件末加入app的初始化代码,并在相应的事件中，加入响应代码即可。</p><div style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"><div><a title="复制代码" style="color: #336699;"><img alt="复制代码" src="http://common.cnblogs.com/images/copycode.gif" style="border: none; max-width: 100%;" /></a></div><pre style="white-space: pre-wrap; word-wrap: break-word;"><span style="color: #008080;">1</span> <span style="color: #0000ff;">class</span> App(wx.App): <span style="color: #008080;">2</span>     <span style="color: #0000ff;">def</span> OnInit(self): <span style="color: #008080;">3</span>         frame = MyFrame1(None)   ##这里为我们生成GUI的Frame类名 <span style="color: #008080;">4</span>         frame.Show() <span style="color: #008080;">5</span>         <span style="color: #0000ff;">return</span> True <span style="color: #008080;">6</span>  <span style="color: #008080;">7</span> app = App() <span style="color: #008080;">8</span>      <span style="color: #008080;">9</span> app.MainLoop()</pre><div><a title="复制代码" style="color: #336699;"><img alt="复制代码" src="http://common.cnblogs.com/images/copycode.gif" style="border: none; max-width: 100%;" /></a></div></div><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"><strong><span style="font-size: 16px;"><br /></span></strong></p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"><strong><span style="font-size: 16px;">5 运行py文件</span></strong></p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;">第一个wxPython的界面程序到这里就完成，有兴趣可以再进行深入研究。</p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;"><img alt="" src="http://pic002.cnblogs.com/images/2011/163390/2011111219252026.png" style="border: none; max-width: 100%;" /></p><p style="color: #333333; font-family: Arial; line-height: 26px; background-color: #ffffff;">&nbsp;</p><img src ="http://www.blogjava.net/pts/aggbug/416370.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/pts/" target="_blank">pts</a> 2014-07-30 16:38 <a href="http://www.blogjava.net/pts/archive/2014/07/30/416370.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>win32 api :  About Messages and Message Queues</title><link>http://www.blogjava.net/pts/archive/2013/07/26/401985.html</link><dc:creator>pts</dc:creator><author>pts</author><pubDate>Fri, 26 Jul 2013 01:56:00 GMT</pubDate><guid>http://www.blogjava.net/pts/archive/2013/07/26/401985.html</guid><wfw:comment>http://www.blogjava.net/pts/comments/401985.html</wfw:comment><comments>http://www.blogjava.net/pts/archive/2013/07/26/401985.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/pts/comments/commentRss/401985.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/pts/services/trackbacks/401985.html</trackback:ping><description><![CDATA[<p><a href="http://msdn.microsoft.com/en-us/library/windows/desktop/ms644927(v=vs.85).aspx#system_defined">http://msdn.microsoft.com/en-us/library/windows/desktop/ms644927(v=vs.85).aspx#system_defined</a></p><p>有关win32 api 大全<br />有关消息的解释，还有一篇文章解释的非常详细：<a href="http://blog.csdn.net/mengde666/article/details/4036398" style="font-size: 14px;">http://blog.csdn.net/mengde666/article/details/4036398</a></p><img src ="http://www.blogjava.net/pts/aggbug/401985.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/pts/" target="_blank">pts</a> 2013-07-26 09:56 <a href="http://www.blogjava.net/pts/archive/2013/07/26/401985.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]python win32api 使用小技巧</title><link>http://www.blogjava.net/pts/archive/2013/07/25/401973.html</link><dc:creator>pts</dc:creator><author>pts</author><pubDate>Thu, 25 Jul 2013 08:40:00 GMT</pubDate><guid>http://www.blogjava.net/pts/archive/2013/07/25/401973.html</guid><wfw:comment>http://www.blogjava.net/pts/comments/401973.html</wfw:comment><comments>http://www.blogjava.net/pts/archive/2013/07/25/401973.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/pts/comments/commentRss/401973.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/pts/services/trackbacks/401973.html</trackback:ping><description><![CDATA[<p style="margin: 10px auto; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 16.66666603088379px; background-color: #ffffff;">From：<a style="font-family: Helvetica, Arial, sans-serif;" href="http://www.cnblogs.com/txw1958/archive/2012/02/16/2353491.html">http://www.cnblogs.com/txw1958/archive/2012/02/16/2353491.html</a></p><p style="margin: 10px auto; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 16.66666603088379px; background-color: #ffffff;">前些日子，由于需要，用python写了个小插件，通过win32api 访问外部程序的窗口 并且做些小操作。</p><p style="margin: 10px auto; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 16.66666603088379px; background-color: #ffffff;">因为原来对win32api 不怎么熟悉 所以只好求救。群里有个QQ：32034767 唐骁勇<a style="margin: 0px; padding: 0px; text-decoration: none; color: #000000; border-bottom-width: 1px; border-bottom-style: dotted; border-bottom-color: #333333;" href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;&#116;&#115;&#121;&#95;&#48;&#48;&#55;&#64;&#49;&#54;&#51;&#46;&#99;&#111;&#109;">tsy_007@163.com</a></p><p style="margin: 10px auto; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 16.66666603088379px; background-color: #ffffff;">这小伙子不错 心热人善</p><p style="margin: 10px auto; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 16.66666603088379px; background-color: #ffffff;">动手之前要选对好工具。（既然是基于WIN32api 当然要用微软的专用的spyxx.exe，上手相当简单。比较专业 ，能查出当前桌面上所有的窗口句柄和类型。VC的那个绿色版的 spy++效果不强（Au3Info.exe也一样），无法追踪多级子窗口。 下面是简易代码：（实际上就是用钩子原理 网络上也可以找到）</p><p style="margin: 10px auto; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 16.66666603088379px; background-color: #ffffff;">import win32ui,win32con,pyHook,pythoncom，win32gui ,wx<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; def hookhandle(event):<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if event.KeyID==9:#tab键值<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; try:<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pwin=win32gui.FindWindow('AfxMDIFrame70',None)#主窗口 AfxMDIFrame70就是你用#spyxx.exe查找到的窗口类名<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pwin1=win32gui.FindWindowEx(pwin,None,'MDIClient',None)<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pwin2=win32gui.FindWindowEx(pwin1,None,'AfxFrameOrView70',None)<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pwin3=win32gui.FindWindowEx(pwin2,None,"AfxOleControl70",None)<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pwin4=win32gui.FindWindowEx(pwin3,None,None,"PatientCardControl Frame")#可以根据窗口#的标题名称查找 标题名称一般外接程序是不变的 而类名有时是变化的 比如机器重启 关闭等&nbsp;<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pwin5=win32gui.FindWindowEx(pwin4,None,"AfxMDIFrame70",None)<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pwin6=win32gui.FindWindowEx(pwin5,None,"AfxWnd70",None)<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pwin7=win32gui.FindWindowEx(pwin6,None,"#32770",None)</p><p style="margin: 10px auto; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 16.66666603088379px; background-color: #ffffff;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; textbox=pwin7.GetDlgItem(222)#获取控件的ID<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; textbox2=pwin7.GetDlgItem(224)</p><p style="margin: 10px auto; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 16.66666603088379px; background-color: #ffffff;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buf='0x0'*1024&nbsp;<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; buf2='0x0'*1024<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; textbox.SendMessage(win32con.WM_SETTEXT,"")#先清空控件内容<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; textbox2.SendMessage(win32con.WM_SETTEXT,"")</p><p style="margin: 10px auto; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 16.66666603088379px; background-color: #ffffff;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oldlen=textbox.SendMessage(win32con.WM_GETTEXT,buf)<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; oldlen2=textbox2.SendMessage(win32con.WM_GETTEXT,buf2)</p><p style="margin: 10px auto; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 16.66666603088379px; background-color: #ffffff;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; textbox.SendMessage(win32con.WM_SETTEXT,buf[0:oldlen]+str(blh))#发送消息 注意不能##用%s 替换 所以一般需要全局变量 来替换<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; textbox2.SendMessage(win32con.WM_SETTEXT,buf2[0:oldlen]+str(name))<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; except:<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; wx.LogMessage('没有发现可用的窗口！请确保程序已经运行')</p><p style="margin: 10px auto; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 16.66666603088379px; background-color: #ffffff;">&nbsp;</p><p style="margin: 10px auto; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 16.66666603088379px; background-color: #ffffff;">&nbsp;</p><p style="margin: 10px auto; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 16.66666603088379px; background-color: #ffffff;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hm = pyHook.HookManager()#初始实例<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hm.KeyDown=hookhandle<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hm.HookKeyboard()<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pythoncom.PumpMessages(5000)#据说是winctype的新功能 延迟吧 具体什么也不清楚&nbsp;<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hm.UnhookKeyboard()#释放键盘捕捉 好像效果不明显<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #for i in range (0,40):<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #win32api.Sleep(20)<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #if win32ui.PumpWaitingMessages(0,-1):<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; win32api.PostQuitMessage(0)# 退出监控消息 很关键 必须配合sys.setrecursionlimit(4000)使用效果##才明显 不然的话 程序无法退出。<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #raise exceptions.SystemExit</p><p style="margin: 10px auto; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 16.66666603088379px; background-color: #ffffff;">&nbsp;</p><p style="margin: 10px auto; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 16.66666603088379px; background-color: #ffffff;">&nbsp;</p><p style="margin: 10px auto; padding: 0px; color: #333333; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 16.66666603088379px; background-color: #ffffff;">&nbsp;&nbsp;&nbsp; def OnClose(self, event):<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sys.setrecursionlimit(4000)#相当关键<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.Close(True)<br style="margin: 0px; padding: 0px;" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.Destroy()</p><img src ="http://www.blogjava.net/pts/aggbug/401973.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/pts/" target="_blank">pts</a> 2013-07-25 16:40 <a href="http://www.blogjava.net/pts/archive/2013/07/25/401973.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【转】python与sqlite中文数据的问题</title><link>http://www.blogjava.net/pts/archive/2013/06/08/400394.html</link><dc:creator>pts</dc:creator><author>pts</author><pubDate>Sat, 08 Jun 2013 06:04:00 GMT</pubDate><guid>http://www.blogjava.net/pts/archive/2013/06/08/400394.html</guid><wfw:comment>http://www.blogjava.net/pts/comments/400394.html</wfw:comment><comments>http://www.blogjava.net/pts/archive/2013/06/08/400394.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/pts/comments/commentRss/400394.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/pts/services/trackbacks/400394.html</trackback:ping><description><![CDATA[<p>&nbsp;</p>
<div class="content-head clearfix" style="zoom: 1; color: #454545; font-family: tahoma, helvetica, arial; font-size: 12px;">
<h2 class="title content-title" style="margin: 0px 0px 10px; padding: 0px; font-size: 20px; font-family: tahoma, helvetica, 'microsoft yahei', arial; color: #3a3a3a; font-weight: normal; float: left;">
<p style="margin: 0px; color: #454545; font-family: tahoma, helvetica, arial; font-size: 14px; padding: 0px;"></p>
</h2>
<h2><a href="http://hi.baidu.com/mxp446533129/item/db9d4b1ac8123b04e65c36ac" target="_blank">【转】python与sqlite中文数据的问题</a></h2>
<br />
sqlite默认编码是utf-8,在我们的PYTHON文件中设置文件保存编码及输出默认编码都为utf-8
<p>&nbsp;</p>
<p style="margin: 0px; color: #454545; font-family: tahoma, helvetica, arial; font-size: 14px; padding: 0px;">在python安装目录lib/site-packages,下新建 sitecustomize.py<br />
输入<br />
import sys<br />
sys.setdefaultencoding('utf-8') #set default encoding to utf-8</p>
<p style="margin: 0px; color: #454545; font-family: tahoma, helvetica, arial; font-size: 14px; padding: 0px;">python运行时自动设置编码为utf-8</p>
<p style="margin: 0px; color: #454545; font-family: tahoma, helvetica, arial; font-size: 14px; padding: 0px;">往sqlite中插入数据然后直接print的时候，需要将数据编码转换为其他编码，比如gbk</p>
<p style="margin: 0px; color: #454545; font-family: tahoma, helvetica, arial; font-size: 14px; padding: 0px;">使用方法:</p>
<p style="margin: 0px; color: #454545; font-family: tahoma, helvetica, arial; font-size: 14px; padding: 0px;">&nbsp;&nbsp;&nbsp;&nbsp; def Utf82Gb(self,str):&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return&nbsp;&nbsp;&nbsp; str.decode('UTF-8').encode('gbk')</p>
<p style="margin: 0px; color: #454545; font-family: tahoma, helvetica, arial; font-size: 14px; padding: 0px;">&nbsp;</p>
<p style="margin: 0px; color: #454545; font-family: tahoma, helvetica, arial; font-size: 14px; padding: 0px;">就可以轻松解决往sqlite中插入中文数据正确显示的问题~</p>
<br /><span style="font-size: 24pt;">重大提醒：</span><br />
<pre><span style="font-size: 14pt;"># Never do this -- insecure! </span><br /><span style="font-size: 14pt;">symbol = 'RHAT' </span><br /><span style="font-size: 14pt;">c.execute("SELECT * FROM stocks WHERE symbol = '%s'" % symbol) </span><br /><span style="font-size: 14pt;">
# Do this instead </span><br /><span style="font-size: 14pt;">t = ('RHAT',) </span><br /><span style="font-size: 14pt;">c.execute('SELECT * FROM stocks WHERE symbol=?', t) </span></pre>
<pre><span style="font-size: 18pt; color: red;"><strong>同时如果涉及到中文，就是仅有一个字段，也要使用tuple形式</strong></span><br />
</pre>
<br />
</div><img src ="http://www.blogjava.net/pts/aggbug/400394.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/pts/" target="_blank">pts</a> 2013-06-08 14:04 <a href="http://www.blogjava.net/pts/archive/2013/06/08/400394.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>python操作sqlite3 碰到中文问题</title><link>http://www.blogjava.net/pts/archive/2013/06/07/400367.html</link><dc:creator>pts</dc:creator><author>pts</author><pubDate>Fri, 07 Jun 2013 11:01:00 GMT</pubDate><guid>http://www.blogjava.net/pts/archive/2013/06/07/400367.html</guid><wfw:comment>http://www.blogjava.net/pts/comments/400367.html</wfw:comment><comments>http://www.blogjava.net/pts/archive/2013/06/07/400367.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/pts/comments/commentRss/400367.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/pts/services/trackbacks/400367.html</trackback:ping><description><![CDATA[<p><span style="color: #333333; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 24px; background-color: #f5f5f5;">错问症状：</span></p>
<p><span style="color: #333333; font-family: Helvetica, Tahoma, Arial, sans-serif;"><span style="line-height: 24px;">OperationalError: Could not decode to UTF-8 column 'shouji_lanshouyuan' with text '国际2部 邬长春'</span></span></p>
<p>解决方案：</p>
<p><span style="color: #333333; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 24px; background-color: #f5f5f5;">conn&nbsp;=&nbsp;sqlite3.connection("&nbsp;...&nbsp;")</span><br style="color: #333333; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 24px; background-color: #f5f5f5;" />
<strong><span style="font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 24px; background-color: #f5f5f5; color: #ff0000;">conn.text_factory&nbsp;=&nbsp;str</span></strong><br style="color: #333333; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 24px; background-color: #f5f5f5;" />
</p>
<p>解决问题方案来源：<a href="http://bbs.csdn.net/topics/250055755">http://bbs.csdn.net/topics/250055755</a></p>
<p><span style="color: #333333; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 24px; background-color: #f5f5f5;">设置python使用什么类型来处理sqlite3的text类型，默认是unicode，所以才会产生</span><br style="color: #333333; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 24px; background-color: #f5f5f5;" />
<span style="color: #333333; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 24px; background-color: #f5f5f5;">OperationalError:&nbsp;Could&nbsp;not&nbsp;decode&nbsp;to&nbsp;UTF-8&nbsp;column&nbsp;'name'&nbsp;with&nbsp;text&nbsp;'国内其他'&nbsp;</span><br style="color: #333333; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 24px; background-color: #f5f5f5;" />
<span style="color: #333333; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 24px; background-color: #f5f5f5;">这个错误</span><br style="color: #333333; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 24px; background-color: #f5f5f5;" />
<br style="color: #333333; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 24px; background-color: #f5f5f5;" />
<span style="color: #333333; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 24px; background-color: #f5f5f5;">因为从数据库中取出数据时，是gbk编码（因为你上次存进去的是gbk）</span><br style="color: #333333; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 24px; background-color: #f5f5f5;" />
<span style="color: #333333; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 24px; background-color: #f5f5f5;">conn.text_factory的默认值是unicode，python会尝试将text类型的字段转换成unicode，就产生了错误</span></p>
<p>&nbsp;</p>
<p><span style="color: #333333; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 24px; background-color: #f5f5f5; font-size: xx-large;">附：sqlite3的row操作：</span></p>
<p><span style="color: #333333; font-family: Helvetica, Tahoma, Arial, sans-serif; line-height: 24px; background-color: #f5f5f5;"></span></p>
<p style="margin: 10px auto; padding: 0px; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;">Row对象的详细介绍<br style="margin: 0px; padding: 0px;" />
</p>
<dl style="margin: 0px; padding: 0px; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;"><dt id="sqlite3.Row" style="margin: 0px; padding: 0px;"><em style="margin: 0px; padding: 0px; font-family: 'Comic Sans MS';">class&nbsp;</em><tt style="margin: 0px; padding: 0px;">sqlite3.</tt><tt style="margin: 0px; padding: 0px;">Row</tt></dt><dd style="margin: 0px; padding: 0px;">
<p style="margin: 10px auto; padding: 0px;"><span style="margin: 0px; padding: 0px; font-family: 'Comic Sans MS';">A&nbsp;</span><a style="margin: 0px; padding: 0px; text-decoration: none; color: #000000; border-bottom-width: 1px; border-bottom-style: dotted; border-bottom-color: #333333;" title="sqlite3.Row" href="http://docs.python.org/library/sqlite3.html#sqlite3.Row"><tt style="margin: 0px; padding: 0px;"><span style="margin: 0px; padding: 0px; font-family: 'Comic Sans MS';">Row</span></tt></a><span style="margin: 0px; padding: 0px; font-family: 'Comic Sans MS';">&nbsp;instance serves as a highly optimized&nbsp;</span><a style="margin: 0px; padding: 0px; text-decoration: none; color: #000000; border-bottom-width: 1px; border-bottom-style: dotted; border-bottom-color: #333333;" title="sqlite3.Connection.row_factory" href="http://docs.python.org/library/sqlite3.html#sqlite3.Connection.row_factory"><tt style="margin: 0px; padding: 0px;"><span style="margin: 0px; padding: 0px; font-family: 'Comic Sans MS';">row_factory</span></tt></a><span style="margin: 0px; padding: 0px; font-family: 'Comic Sans MS';">&nbsp;for&nbsp;</span><a style="margin: 0px; padding: 0px; text-decoration: none; color: #000000; border-bottom-width: 1px; border-bottom-style: dotted; border-bottom-color: #333333;" title="sqlite3.Connection" href="http://docs.python.org/library/sqlite3.html#sqlite3.Connection"><tt style="margin: 0px; padding: 0px;"><span style="margin: 0px; padding: 0px; font-family: 'Comic Sans MS';">Connection</span></tt></a><span style="margin: 0px; padding: 0px; font-family: 'Comic Sans MS';">&nbsp;objects. It tries to mimic a tuple in most of its features.</span></p>
<p style="margin: 10px auto; padding: 0px;"><span style="margin: 0px; padding: 0px; font-family: 'Comic Sans MS';">It supports mapping access by column name and index, iteration, representation, equality testing and&nbsp;</span><a style="margin: 0px; padding: 0px; text-decoration: none; color: #000000; border-bottom-width: 1px; border-bottom-style: dotted; border-bottom-color: #333333;" title="len" href="http://docs.python.org/library/functions.html#len"><tt style="margin: 0px; padding: 0px;"><span style="margin: 0px; padding: 0px; font-family: 'Comic Sans MS';">len()</span></tt></a><span style="margin: 0px; padding: 0px; font-family: 'Comic Sans MS';">.</span></p>
<p style="margin: 10px auto; padding: 0px;"><span style="margin: 0px; padding: 0px; font-family: 'Comic Sans MS';">If two&nbsp;</span><a style="margin: 0px; padding: 0px; text-decoration: none; color: #000000; border-bottom-width: 1px; border-bottom-style: dotted; border-bottom-color: #333333;" title="sqlite3.Row" href="http://docs.python.org/library/sqlite3.html#sqlite3.Row"><tt style="margin: 0px; padding: 0px;"><span style="margin: 0px; padding: 0px; font-family: 'Comic Sans MS';">Row</span></tt></a><span style="margin: 0px; padding: 0px; font-family: 'Comic Sans MS';">&nbsp;objects have exactly the same columns and their members are equal, they compare equal.</span></p>
<p style="margin: 10px auto; padding: 0px;"><span style="margin: 0px; padding: 0px; font-family: 'Comic Sans MS';">Changed in version 2.6: Added iteration and equality (hashability).</span></p>
<dl style="margin: 0px; padding: 0px;"><dt id="sqlite3.Row.keys" style="margin: 0px; padding: 0px;"><tt style="margin: 0px; padding: 0px;"><span style="margin: 0px; padding: 0px; font-family: 'Comic Sans MS';">keys</span></tt><big style="margin: 0px; padding: 0px;"><span style="margin: 0px; padding: 0px; font-family: 'Comic Sans MS';">(</span></big><big style="margin: 0px; padding: 0px;"><span style="margin: 0px; padding: 0px; font-family: 'Comic Sans MS';">)</span></big></dt><dd style="margin: 0px; padding: 0px;">
<p style="margin: 10px auto; padding: 0px;"><span style="margin: 0px; padding: 0px; font-family: 'Comic Sans MS';">This method returns a tuple of column names. Immediately after a query, it is the first member of each tuple in&nbsp;</span><a style="margin: 0px; padding: 0px; text-decoration: none; color: #000000; border-bottom-width: 1px; border-bottom-style: dotted; border-bottom-color: #333333;" title="sqlite3.Cursor.description" href="http://docs.python.org/library/sqlite3.html#sqlite3.Cursor.description"><tt style="margin: 0px; padding: 0px;"><span style="margin: 0px; padding: 0px; font-family: 'Comic Sans MS';">Cursor.description</span></tt></a><span style="margin: 0px; padding: 0px; font-family: 'Comic Sans MS';">.</span></p>
<p style="margin: 10px auto; padding: 0px;"><span style="margin: 0px; padding: 0px; font-family: 'Comic Sans MS';">New in version 2.6.</span></p>
</dd></dl></dd></dl>
<p style="margin: 10px auto; padding: 0px; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; background-color: #ffffff;">&nbsp; &nbsp; 下面举例说明</p>
<div class="cnblogs_code" style="margin: 5px 0px; padding: 5px; font-family: 'Courier New'; font-size: 12px; border: 1px solid #cccccc; overflow: auto;">
<div class="cnblogs_code_toolbar" style="margin: 5px 0px 0px; padding: 0px;"><span class="cnblogs_code_copy" style="margin: 0px; padding: 0px 5px 0px 0px; line-height: 1.5;"><a style="margin: 0px; padding: 0px; text-decoration: none; color: #000000; border: none !important;" title="复制代码"><img style="margin: 0px; padding: 0px; border: none !important;" src="http://common.cnblogs.com/images/copycode.gif" alt="复制代码" /></a></span></div>
<div style="margin: 0px; padding: 0px;"><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">cx.row_factory&nbsp;</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">=</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">&nbsp;sqlite3.Row<br style="margin: 0px; padding: 0px;" />
<br style="margin: 0px; padding: 0px;" />
</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">c&nbsp;</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">=</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">&nbsp;cx.cursor()<br style="margin: 0px; padding: 0px;" />
<br style="margin: 0px; padding: 0px;" />
</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">c.execute(</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #800000;">'</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #800000;">select&nbsp;*&nbsp;from&nbsp;catalog</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #800000;">'</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">)</span></div>
<div style="margin: 0px; padding: 0px;"><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">&nbsp;</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">&lt;</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">sqlite3.Cursor&nbsp;object&nbsp;at&nbsp;</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">0x05666680</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">&gt;</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;"><br style="margin: 0px; padding: 0px;" />
<br style="margin: 0px; padding: 0px;" />
</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">r&nbsp;</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">=</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">&nbsp;c.fetchone()<br style="margin: 0px; padding: 0px;" />
<br style="margin: 0px; padding: 0px;" />
</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">type(r)<br style="margin: 0px; padding: 0px;" />
</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">&lt;</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">type&nbsp;</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #800000;">'</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #800000;">sqlite3.Row</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #800000;">'</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">&gt;</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;"><br style="margin: 0px; padding: 0px;" />
<br style="margin: 0px; padding: 0px;" />
</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">r<br style="margin: 0px; padding: 0px;" />
</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">&lt;</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">sqlite3.Row&nbsp;object&nbsp;at&nbsp;</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">0x05348980</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">&gt;</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;"><br style="margin: 0px; padding: 0px;" />
<br style="margin: 0px; padding: 0px;" />
</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #0000ff;">print</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">&nbsp;r<br style="margin: 0px; padding: 0px;" />
(0,&nbsp;</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">10</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">,&nbsp;u</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #800000;">'</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #800000;">\u9c7c</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #800000;">'</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">,&nbsp;u</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #800000;">'</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #800000;">Yu</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #800000;">'</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">)<br style="margin: 0px; padding: 0px;" />
<br style="margin: 0px; padding: 0px;" />
</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">len(r)<br style="margin: 0px; padding: 0px;" />
</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">4</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;"><br style="margin: 0px; padding: 0px;" />
<br style="margin: 0px; padding: 0px;" />
</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">r[</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">2</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #使用索引查询<br style="margin: 0px; padding: 0px;" />
</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">u</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #800000;">'</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #800000;">\u9c7c</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #800000;">'</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;"><br style="margin: 0px; padding: 0px;" />
<br style="margin: 0px; padding: 0px;" />
</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">r.keys()<br style="margin: 0px; padding: 0px;" />
</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">[</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #800000;">'</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #800000;">id</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #800000;">'</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">,&nbsp;</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #800000;">'</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #800000;">pid</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #800000;">'</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">,&nbsp;</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #800000;">'</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #800000;">name</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #800000;">'</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">,&nbsp;</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #800000;">'</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #800000;">nickname</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #800000;">'</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">]<br style="margin: 0px; padding: 0px;" />
<br style="margin: 0px; padding: 0px;" />
<span style="background-color: #ffffff; font-family: verdana, Arial, Helvetica, sans-serif; line-height: 25px; color: #333333; font-size: 14px;">&nbsp;使用列的关键词查询</span></span></div>
<div style="margin: 0px; padding: 0px;"><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;"></span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">In&nbsp;[</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">43</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">]:&nbsp;r[</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #800000;">'</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #800000;">id</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #800000;">'</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">]</span></div>
<div style="margin: 0px; padding: 0px;"><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">Out[</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">43</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">]:&nbsp;0</span></div>
<div style="margin: 0px; padding: 0px;"><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">In&nbsp;[</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">44</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">]:&nbsp;r[</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #800000;">'</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #800000;">name</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #800000;">'</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">]</span></div>
<div style="margin: 0px; padding: 0px;"><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">Out[</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">44</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #000000;">]:&nbsp;u</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #800000;">'</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #800000;">\u9c7c</span><span style="margin: 0px; padding: 0px; line-height: 1.5; color: #800000;">'</span></div>
</div>
<p>&nbsp;</p><img src ="http://www.blogjava.net/pts/aggbug/400367.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/pts/" target="_blank">pts</a> 2013-06-07 19:01 <a href="http://www.blogjava.net/pts/archive/2013/06/07/400367.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>为pamie增加两个有关获取指定td、tr的函数</title><link>http://www.blogjava.net/pts/archive/2013/06/07/400351.html</link><dc:creator>pts</dc:creator><author>pts</author><pubDate>Fri, 07 Jun 2013 06:59:00 GMT</pubDate><guid>http://www.blogjava.net/pts/archive/2013/06/07/400351.html</guid><wfw:comment>http://www.blogjava.net/pts/comments/400351.html</wfw:comment><comments>http://www.blogjava.net/pts/archive/2013/06/07/400351.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/pts/comments/commentRss/400351.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/pts/services/trackbacks/400351.html</trackback:ping><description><![CDATA[<p>&nbsp;</p><p>&nbsp; &nbsp; def getTdOfTableContains(self,table,conText):</p><p>&nbsp; &nbsp; &nbsp; &nbsp; #add 20130607 by sho</p><p>&nbsp; &nbsp; &nbsp; &nbsp; #find first td in table and td's innertext contains conText</p><p>&nbsp; &nbsp; &nbsp; &nbsp; for cell in table.cells:</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if conText in cell.innertext:</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return cell</p><p>&nbsp; &nbsp; &nbsp; &nbsp; return None</p><p>&nbsp;</p><p>&nbsp; &nbsp; def getTrOfTableContains(self,table,conText):</p><p>&nbsp; &nbsp; &nbsp; &nbsp; #add 20130607 by sho</p><p>&nbsp; &nbsp; &nbsp; &nbsp; #find first tr in table and tr's cells contains conText</p><p>&nbsp; &nbsp; &nbsp; &nbsp; td=self.getTdOfTableContains(table,conText)</p><p>&nbsp; &nbsp; &nbsp; &nbsp; if td:</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return self.getElementParent(td)</p><p>&nbsp; &nbsp; &nbsp; &nbsp; else:</p><p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return None</p><p>测试代码：</p><p>&nbsp;</p><p>*** 远程解释器再初始化了 &nbsp;***</p><p>&gt;&gt;&gt; from PAM30 import PAMIE</p><p>&gt;&gt;&gt; ie=PAMIE("http://1.1.1.1/query/itemQueryAction.do?method=jumpToSingleItemTrackQuery")</p><p>&gt;&gt;&gt; ie.setTextBox("itemno","1191590659011")</p><p>True</p><p>&gt;&gt;&gt; ie.submitForm("itemQueryForm")</p><p>True</p><p>&gt;&gt;&gt; tb4=ie.findElement("table","classname","table4")</p><p>&gt;&gt;&gt; tr_sj=ie.getTrOfTableContains(tb4,u"收寄")</p><p>&gt;&gt;&gt; print tr_sj.outerhtml</p><p>&nbsp;</p><p>&nbsp;</p><img src ="http://www.blogjava.net/pts/aggbug/400351.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/pts/" target="_blank">pts</a> 2013-06-07 14:59 <a href="http://www.blogjava.net/pts/archive/2013/06/07/400351.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>pamie 中getElementsList对中文内容的处理</title><link>http://www.blogjava.net/pts/archive/2012/08/29/386543.html</link><dc:creator>pts</dc:creator><author>pts</author><pubDate>Wed, 29 Aug 2012 13:48:00 GMT</pubDate><guid>http://www.blogjava.net/pts/archive/2012/08/29/386543.html</guid><wfw:comment>http://www.blogjava.net/pts/comments/386543.html</wfw:comment><comments>http://www.blogjava.net/pts/archive/2012/08/29/386543.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/pts/comments/commentRss/386543.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/pts/services/trackbacks/386543.html</trackback:ping><description><![CDATA[<div>pamie 中getElementsList方法对于查找tag的innertext属性是中文是会出错，需要修改pamie30文件的第959行，增加给出的属性是中文时的判断方式，不需要str(valText)方法检验：<br />if not isinstance(valText):<br />&nbsp;&nbsp;&nbsp; valText = str(valText)<br />如此以来，比如查找innertext为&#8220;中文&#8221;的td list时，可使用如下方法：<br />1、val=u"中文"<br />2、td_list=ie.getElementsList("td","innertext="+val)</div><img src ="http://www.blogjava.net/pts/aggbug/386543.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/pts/" target="_blank">pts</a> 2012-08-29 21:48 <a href="http://www.blogjava.net/pts/archive/2012/08/29/386543.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>pamie 中对网页中有&lt;br&gt;的处理</title><link>http://www.blogjava.net/pts/archive/2012/08/27/386386.html</link><dc:creator>pts</dc:creator><author>pts</author><pubDate>Mon, 27 Aug 2012 14:56:00 GMT</pubDate><guid>http://www.blogjava.net/pts/archive/2012/08/27/386386.html</guid><wfw:comment>http://www.blogjava.net/pts/comments/386386.html</wfw:comment><comments>http://www.blogjava.net/pts/archive/2012/08/27/386386.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/pts/comments/commentRss/386386.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/pts/services/trackbacks/386386.html</trackback:ping><description><![CDATA[比如网页中有如下代码：<br />&lt;td&gt;2012-3-8&lt;br&gt;12:10:00&lt;/td&gt;<br />使用td.innertext获得的是2012-3-8\r\n12:10:00<br />因此要替换必须使用replace("\r\n","替换的新内容")，简单使用\n不行！！！费了我2个小时才发现。<br />因为使用innertext属性后，&lt;br&gt;直接转换为\r\n，而不是\n<img src ="http://www.blogjava.net/pts/aggbug/386386.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/pts/" target="_blank">pts</a> 2012-08-27 22:56 <a href="http://www.blogjava.net/pts/archive/2012/08/27/386386.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【转】JavaScript Table、TableRow、TableCell属性、方法、事件</title><link>http://www.blogjava.net/pts/archive/2012/01/06/368032.html</link><dc:creator>pts</dc:creator><author>pts</author><pubDate>Fri, 06 Jan 2012 11:19:00 GMT</pubDate><guid>http://www.blogjava.net/pts/archive/2012/01/06/368032.html</guid><wfw:comment>http://www.blogjava.net/pts/comments/368032.html</wfw:comment><comments>http://www.blogjava.net/pts/archive/2012/01/06/368032.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/pts/comments/commentRss/368032.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/pts/services/trackbacks/368032.html</trackback:ping><description><![CDATA[<li>
<div>
<h2>JavaScript Table、TableRow、TableCell属性、方法、事件</h2></div></li><li>
<div class="subtitle"><span>Sat Oct 15 15:18:16 CST 2011</span> <span>一家理财网(整理)</span> <span><a id="favorite" href="javascript:void(0);" jquery1325848460718="10">我要收藏(<span style="color: red" id="favorite_show1">0</span>)</a></span> <span><a href="../../pinglun/neirong/41.html">我要评论(<span style="color: red" id="comment_show1">0</span>)</a></span> </div></li><li>
<div class="articleContent">
<p>Table表格对象&nbsp;&nbsp;Table对象:表示HTML文档中的表，对于文档中每个&lt;table&gt;标记，浏览器都创建一个Table对象.</p>
<p>&nbsp;</p>
<table border="1" width="700">
<tbody>
<tr>
<td colspan="2">Table对象集合</td></tr>
<tr>
<td width="236">集合</td>
<td width="448">描述</td></tr>
<tr>
<td>cells[]</td>
<td>获取包含表格中所有单元格的数组</td></tr>
<tr>
<td>rows[]</td>
<td>获取包含表格中所有行的数组</td></tr>
<tr>
<td>tBodies[]</td>
<td>获取包含表格中所有tbody的数组</td></tr>
<tr>
<td colspan="2">Table对象属性</td></tr>
<tr>
<td>border</td>
<td>设置或获取表格边框</td></tr>
<tr>
<td>caption</td>
<td>设置或获取表格标题</td></tr>
<tr>
<td>cellPadding</td>
<td>设置或获取每个单元格边框与内容的宽度</td></tr>
<tr>
<td>cellSpacing</td>
<td>设置或获取表格中单元格的间距</td></tr>
<tr>
<td>frame</td>
<td>设置或获取表格具有哪些边框</td></tr>
<tr>
<td>rules</td>
<td>设置或获取表格中的内部边框</td></tr>
<tr>
<td>summary</td>
<td>设置或获取表格的描述</td></tr>
<tr>
<td>tFoot</td>
<td>获取表格的tFoot对象</td></tr>
<tr>
<td>tHead</td>
<td>获取表格的tHead对象</td></tr>
<tr>
<td>width</td>
<td>设置或获取表格宽度</td></tr>
<tr>
<td colspan="2">Table对象方法</td></tr>
<tr>
<td>createCaption()</td>
<td>为表格创建一个空的标题元素</td></tr>
<tr>
<td>createTFoot()</td>
<td>为表格创建一个空的tFoot元素</td></tr>
<tr>
<td>createTHead()</td>
<td>为表格创建一个空的tHead元素</td></tr>
<tr>
<td>deleteCaption()</td>
<td>删除表格的标题元素</td></tr>
<tr>
<td>deleteRow()</td>
<td>删除指定的表格行</td></tr>
<tr>
<td>deleteTFoot()</td>
<td>删除表格的tFoot元素</td></tr>
<tr>
<td>deleteTHead()</td>
<td>删除表格的tHead元素</td></tr>
<tr>
<td>insertRow()</td>
<td>向表格中插入新行</td></tr></tbody></table>
<p>&nbsp;</p>
<p>TableCell对象:表示HTML文档中表的单元格，对于文档中每个&lt;td&gt;标记，浏览器都创建一个TableCell对象.</p>
<p>&nbsp;</p>
<table border="1" width="700">
<tbody>
<tr>
<td colspan="2">TableCell对象属性</td></tr>
<tr>
<td width="236">属性</td>
<td width="448">描述</td></tr>
<tr>
<td>abbr</td>
<td>设置或获取单元格的摘要</td></tr>
<tr>
<td>align</td>
<td>设置或获取单元格中文字的水平对齐方向</td></tr>
<tr>
<td>axis</td>
<td>设置或获取以逗号分隔的相关单元格组成的列表</td></tr>
<tr>
<td>cellIndex</td>
<td>获取行单元格集合中某单元格的位置</td></tr>
<tr>
<td>ch</td>
<td>设置或获取单元格的对齐特征</td></tr>
<tr>
<td>chOff</td>
<td>设置或获取单元格的对齐偏移特征</td></tr>
<tr>
<td>colSpan</td>
<td>设置或获取单元格跨越的表格列数</td></tr>
<tr>
<td>headers</td>
<td>设置或获取以空格分表头单元格的id列表</td></tr>
<tr>
<td>height</td>
<td>设置或获取单元格的高度</td></tr>
<tr>
<td>innerHTML</td>
<td>设置或获取单元格标记间的HTML文本</td></tr>
<tr>
<td>noWrap</td>
<td>设置或获取单元格是否自动换行</td></tr>
<tr>
<td>rowSpan</td>
<td>设置或获取单元格跨越的表格行数</td></tr>
<tr>
<td>scope</td>
<td>设置或获取与标题相关联的数据列</td></tr>
<tr>
<td>vAlign</td>
<td>设置或获取单元格文字的垂直对齐方向</td></tr>
<tr>
<td>width</td>
<td>设置或获取单元格的宽度</td></tr></tbody></table>
<p>&nbsp;</p>
<p>TableRow对象:表示HTML文档中表的行，对于文档中每个&lt;tr&gt;标记，浏览器都创建一个TableRow对象.</p>
<p>&nbsp;</p>
<table border="1" width="700">
<tbody>
<tr>
<td colspan="2">TableRow对象集合</td></tr>
<tr>
<td width="236">集合</td>
<td width="448">描述</td></tr>
<tr>
<td>cells[]</td>
<td>获取表格行中所有列组成的数组</td></tr>
<tr>
<td colspan="2">Table对象属性</td></tr>
<tr>
<td>accessKey</td>
<td>设置或获取该对象的快捷键</td></tr>
<tr>
<td>align</td>
<td>设置或获取表格行中单元格中文字的水平对齐方向</td></tr>
<tr>
<td>chOff</td>
<td>设置或获取单元格的对齐偏移特征</td></tr>
<tr>
<td>colSpan</td>
<td>设置或获取单元格跨越的表格列数</td></tr>
<tr>
<td>height</td>
<td>设置或获取表格行的高度</td></tr>
<tr>
<td>innerHTML</td>
<td>设置或获取表格行标记间的HTML文本</td></tr>
<tr>
<td>innerText</td>
<td>设置或获取表格行标记间的文本</td></tr>
<tr>
<td>rowIndex</td>
<td>获取表格行对象在表格行集合中的位置</td></tr>
<tr>
<td>sectionRowIndex</td>
<td>获取tBody，tHead或tFoot中，表格行对象在行集合中的位置</td></tr>
<tr>
<td>tabIndex</td>
<td>设置或获取表格行的Tab顺序索引</td></tr>
<tr>
<td>vAlign</td>
<td>设置或获取表格行中文字的垂直对齐方向</td></tr>
<tr>
<td>width</td>
<td>设置或获取表格行的宽度</td></tr>
<tr>
<td colspan="2">TableRow对象方法</td></tr>
<tr>
<td>blur()</td>
<td>取消该对象的激活状态</td></tr>
<tr>
<td>click()</td>
<td>模拟鼠标单击该对象</td></tr>
<tr>
<td>deleteCell([i])</td>
<td>删除表格行中的指定的单元格</td></tr>
<tr>
<td>focus()</td>
<td>将焦点移至表格行</td></tr>
<tr>
<td>insertCell()</td>
<td>在表格行中插入新单元格</td></tr></tbody></table>
<p>&nbsp;</p></div></li><li>信息来源：http://www.efamilly.com <a title="如果您觉得该篇文章侵犯了您的版权或所描述内容严重偏离客观事实，您可以在此申诉或投诉。" href="javascript:void(0)">(举报这篇文章)</a></li><img src ="http://www.blogjava.net/pts/aggbug/368032.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/pts/" target="_blank">pts</a> 2012-01-06 19:19 <a href="http://www.blogjava.net/pts/archive/2012/01/06/368032.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用python发飞信</title><link>http://www.blogjava.net/pts/archive/2011/12/18/366687.html</link><dc:creator>pts</dc:creator><author>pts</author><pubDate>Sun, 18 Dec 2011 15:40:00 GMT</pubDate><guid>http://www.blogjava.net/pts/archive/2011/12/18/366687.html</guid><wfw:comment>http://www.blogjava.net/pts/comments/366687.html</wfw:comment><comments>http://www.blogjava.net/pts/archive/2011/12/18/366687.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/pts/comments/commentRss/366687.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/pts/services/trackbacks/366687.html</trackback:ping><description><![CDATA[1、使用的扩展包PyFetion：<a href="http://code.google.com/p/pytool/">http://code.google.com/p/pytool/<br />2</a>、将三个文件（实际上主要是pyfetion 和 rea）安装到python扩展包目录下<br />3、开始使用了，简单的代码：<br />from PyFetion import *<br /><div>phone = PyFetion('13888888888','password','TCP',debug=True)</div>phone.login(FetionOnline)<br />phone.send_sms("test")<br />4、验证码，就在执行当前python命令的目录下，有个fetion_verify.bmp文件，就是验证码的图片<br />5、有个介绍：<a href="http://code.google.com/p/pytool/issues/detail?id=39">http://code.google.com/p/pytool/issues/detail?id=39</a>，通过修改config文件，可以避免每次输入验证码<br />6、发送中文，需要用到fetion.py中的toUTF8这个方法，当然也可以自己做：<br /><div><div>def toUTF8(str):</div><div>&nbsp; &nbsp; return str.decode((os.name == 'posix' and 'utf-8' or 'cp936')).encode('utf-8')<br />7、接收信息：<br />ret=phone.receive()<br />for e in ret:<br />&nbsp; &nbsp; if e[0]=='Message:<br />&nbsp; &nbsp; &nbsp; &nbsp; print e<br />信息无法重复读取。</div></div><img src ="http://www.blogjava.net/pts/aggbug/366687.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/pts/" target="_blank">pts</a> 2011-12-18 23:40 <a href="http://www.blogjava.net/pts/archive/2011/12/18/366687.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【转】PAMIE- Python实现IE自动化的模块</title><link>http://www.blogjava.net/pts/archive/2011/05/16/350350.html</link><dc:creator>pts</dc:creator><author>pts</author><pubDate>Mon, 16 May 2011 13:51:00 GMT</pubDate><guid>http://www.blogjava.net/pts/archive/2011/05/16/350350.html</guid><wfw:comment>http://www.blogjava.net/pts/comments/350350.html</wfw:comment><comments>http://www.blogjava.net/pts/archive/2011/05/16/350350.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/pts/comments/commentRss/350350.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/pts/services/trackbacks/350350.html</trackback:ping><description><![CDATA[<p id="aeaoofnhgocdbnbeljkmbjdmhbcokfdb-mousedown" style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">from:<span style="font-size: medium; color: #000000; line-height: normal; font-family: Simsun"><a href="http://blog.csdn.net/sding/archive/2009/10/16/4679110.aspx">http://blog.csdn.net/sding/archive/2009/10/16/4679110.aspx</a></span></p>
<p id="" style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">PAMIE是一套为Python写的用于Web自动化测试的工具，采用Win32COM的方式操作IE来实现。<br />pamie是个很好的操作IE的模块<br />用pamie来操作ie浏览器好方便啊，本来它就是一个IE测试自动化的东西，<br />这样，用pamie来抓取网页，自动提交表单很容易。</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">使用：<br />来测试一个最简单的例子：</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif"><br />from cPAMIE import PAMIE</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">ie = PAMIE()</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">ie.navigate("google.com")<br />ie.textBoxSet('q','python')<br />ie.buttonClick('btnG')<br />ie.linkClick('Python Programming Language -- Official Website')<br />ie.windowChange('Python Programming Language -- Official Website')<br />ie.windowFind('Python Programming Language -- Official Website')<br />ie.textBoxSet('q',"Automation")<br />ie.buttonClick('submit')</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif"><br />直接操作页面上的form元素，访问页面的文本信息，来判断用户登陆是否成功。</p>
<p id="" style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif"><br />pamie中怎样处理中文标题的弹出对话框?<br /><a style="color: #6fbc4c; text-decoration: none" href="http://www.python-forum.org/pythonforum/viewtopic.php?f=17&amp;t=3194">http://www.python-forum.org/pythonforum/viewtopic.php?f=17&amp;t=3194</a>&nbsp;<br /><a style="color: #6fbc4c; text-decoration: none" href="http://markmail.org/message/u3ojkyj2ns7p3dn3#query:+page:1+mid:5wuwfctervph6tlv+state:results">http://markmail.org/message/u3ojkyj2ns7p3dn3#query:+page:1+mid:5wuwfctervph6tlv+state:results</a>&nbsp;<br />python：</p>
<p id="" style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">import cPAMIE, cModalPopUp, winGuiAuto<br />import time</p>
<p id="" style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">ie = cPAMIE.PAMIE()<br />wga = winGuiAuto</p>
<p id="" style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif"># 登录<br />ie.navigate('D:\\python\\WebDialogTest\\1.html')</p>
<p id="" style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">#启动新的进程，自动点击"取消"<br />clickCancel = cModalPopUp.handlePopup("Confirm","取消")<br />clickCancel.popupName = "选择文件"<br />clickCancel.start()</p>
<p id="" style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">ie.buttonClick("install")<br />time.sleep(1)</p>
<p id="" style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">clickCancel.join() #进程结束</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">-------------------------------------------------------------------------------------------------------------------------------------</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">另外一篇介绍:</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif"><a style="color: #006bad; text-decoration: none" href="http://pamie.sourceforge.net/">PAMIE</a>&nbsp;是一个很有意思的模块。它是一个实现IE自动化的模块。在此之前我使用过ClientCookie这个模块，它可以使用urllib2来通过程序访问页 面，并且很适合在需要cookie支持的环境中。不过，有些web的访问过程并不仅仅是下载文件这样的事情，有时是一系统的动作。PAMIE应该是一个更 直观，更简单的模拟手工输入的过程。不过，局限就是它只支持IE，在某些特殊情况下还是可以的。</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">使用它的话你需要安装win32all模块。</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">下面是它的<a style="color: #6fbc4c; text-decoration: none" href="http://pamie.sourceforge.net/README.html">readme</a>&nbsp;提供的一个简单示例：</p>
<blockquote dir="ltr" style="border-right: #98a47f 1px dotted; padding-right: 10px; border-top: #98a47f 1px dotted; padding-left: 10px; padding-bottom: 10px; margin: 10px 0px; font: 14px/21px verdana, sans-serif; border-left: #98a47f 1px dotted; padding-top: 10px; border-bottom: #98a47f 1px dotted; background-color: #f5f5f5; background-origin: initial; background-clip: initial">
<p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; padding-top: 0px">import cPAMIE</p>
<p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; padding-top: 0px">ie= cPAMIE.PAMIE()</p>
<p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; padding-top: 0px"># Start Script:</p>
<p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; padding-top: 0px">ie.Navigate ('http://pamie.sourceforge.net/pamieform.html')<br />ie.SetTextBox('John','firstname',0)<br />ie.SetTextBox('Doe','lastname',0)<br />ie.SetTextBox('1020 State Street','Addline1',0)<br />ie.SetTextBox('Suite #16','Addline2',0)<br />ie.SetTextBox('San Mateo','city',0)<br />ie.SetListBox('CA','state',0)<br />ie.SetTextBox('90210','zip',0)</p>
<p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; padding-top: 0px">ie.ClickButton('Submit',0)</p></blockquote>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">那 么在我们下载完这个模块之后，它是一个zip包。它没有做成安装模式，可以自行将cPAMIE.py拷贝到python安装目录下的lib子目录中即可。 上面的代码很简单，先导入cPAMIE模块，然后生成一个自动化对象ie。这时我们会看到程序自动打开一个ie窗口，我们的操作可以在这个ie窗口中看 到，执行的部分以黄底显示。</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">ie.Navigate()用来访问一个链接。<br />ie.SetTextBox()用来设置一个文本域的值。第一个参数为输入的值，第二个参数为对应的form表格的Input域的名字（这一点需要查看源码才知识），第三个是form的名字（示例为0表示下标）。<br />ie.SetListBox()用来设置列表框的值。<br />ie.ClickButton()用来模拟点击按钮。第一个参数是按钮的名字，第二个参数为0表示下标。</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">在PAMIE主页中写出了一些可用的其它的方法，如ClickLink()。它的第一个参数为链接对应的文本，如果是中文，转成unicode即可。如页面是GB2312，链接源码为：</p>
<blockquote dir="ltr" style="border-right: #98a47f 1px dotted; padding-right: 10px; border-top: #98a47f 1px dotted; padding-left: 10px; padding-bottom: 10px; margin: 10px 0px; font: 14px/21px verdana, sans-serif; border-left: #98a47f 1px dotted; padding-top: 10px; border-bottom: #98a47f 1px dotted; background-color: #f5f5f5; background-origin: initial; background-clip: initial">
<p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; padding-top: 0px">&lt;a href="http://xxx.com"&gt;汉字&lt;/a&gt;</p></blockquote>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">调用如下：</p>
<blockquote dir="ltr" style="border-right: #98a47f 1px dotted; padding-right: 10px; border-top: #98a47f 1px dotted; padding-left: 10px; padding-bottom: 10px; margin: 10px 0px; font: 14px/21px verdana, sans-serif; border-left: #98a47f 1px dotted; padding-top: 10px; border-bottom: #98a47f 1px dotted; background-color: #f5f5f5; background-origin: initial; background-clip: initial">
<p style="padding-right: 0px; padding-left: 0px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; padding-top: 0px">ie.ClickButton(unicode('汉字', 'cp936'))</p></blockquote>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">在实际运行中可能不需要这样，只要参数是unicode编码即可。</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">同时如果你查看源码，还可以看到一些其它的方法：</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">Quit() -- 关闭打开的ie<br />GoBack() -- 后退<br />Refresh() -- 刷新</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">大家有兴趣可以试一试，一边操作一边就可以看到结果，很简单也很方便。</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">-------------------------------------------------------------------------------------------------------------------------------</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">第三个文章介绍</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">简单明了的Python,第三方提供的模块或称组件 module 等 也很简单明了的</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">下面是 一个 例子所列举的功能较全了 代码加注解...</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif"># -*- coding: cp936 -*-<br />import sys</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">#我把cPAMIE等 pamie2.0里的所有文件放在了 如下路径的 名为pamie 的文件夹里了 加进sys.path方便import 出所有pamie文件夹里的 模块<br />#只要能import CPAMIE 这里的例子就可运行了呵呵<br />sys.path.append(r"F:\Python25\lib\site-packages\pamie")<br />import cPAMIE</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">#new 实例<br />ie= cPAMIE.PAMIE()</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">#打开目标网页</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">ie.navigate ('http://pamie.sourceforge.net/pamieform.html')</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">#注意下面所列的 第一个参数如 fistname 等 都是 网页源代码里的 input name="firstname"<br />#里找出来的,不能用 网页上看见的黑体字: "First Name:"<br />#填文本框<br />ie.textBoxSet('firstname','JustThisName')</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">ie.textBoxSet('lastname','Iamhere')</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">#先择下拉菜单:</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">ie.listBoxSelect('state',"MS")</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">#方形选择框:</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">ie.checkBoxSet('cxbx',1) #1 2 3 或 * 号等都是 "勾选"的意思 '' 空字符串代表取消选择</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">#圆形选择框: 英语是 radio 做过网页设计就容易知道这些元素的命名了<br />#这里选择 Jazz<br />ie.radioButtonSet("music","Jazz") # music是这个 选择列表的名字,从网页源代码里找出</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif"><br />#最后提交按钮</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">print "now 提交按钮,只要再Python解释器里输入下面这句就 提交 了"<br />#ie.buttonClick("Submit") 用来取代鼠标点击 方便多了</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">#源代码里是 input type="submit" name="Submit" 所以 第一个参数就是name的值"Submit"<br />#pamie是共分 大小写的</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">#ie.buttonClick("Submit")</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">#IE有自已的特性, 好像用 pamie 打开多个网页,都是加在同一个IE进程里的,不是一个网页一个进程</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">'''很多网页较复杂,有图片按钮, javaScript按钮 等的... 若是 图片类按钮<br />用 ie.buttonImageClick("submitRegister")</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">有些按钮是 鼠标点击后 会执行一个 javascript 来提交内容的 如源代码里内容是:<br />&lt;input type="image" src="<a style="color: #6fbc4c; text-decoration: none" href="http://www.sit.com/member/images/register.gif">http://www.sit.com/member/images/register.gif</a>&nbsp;" width="100" height="54" border="0"<br />onClick="javascript:submitMe();<br />就是说 点击 那个 叫做 register.gif的图片会 会执行 javascript:submitMe() 来提交页面...时 可用:</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">ie.javaScriptExecute("javascript:submitMe()")&nbsp;&nbsp; 来自动提交页面. 这类按钮 鼠标移上去后,IE左下角一般会出现 相应的</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">javascript:theFunction() 很容易找...</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">执行 带参数的 javascript function 也是可以的... ie.javaScriptExecute("javascript:submitMe('param')")<br />也可直接设置一个 网页里元素的值:<br />例如 网页源文件里 设置了 document.Form.id.value="string" 可用下面语句直接更改</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">ie.javaScriptExecute("javascript:document.Form.id.value='theValueYouWant'")</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif"><br />另外: pamie2.0 里有个 模块用来处理 简单的 弹出窗口 这类窗口的标题一般为: Microsoft Internet Explorer</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">import cModalPopUp</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">a=cModalPopUp.handlePopup('Confirm',"确定") #"第二个参数是 "确定",表示 弹出窗口的按钮上的 文字是 "确定"这二个字</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">如图:</p>
<div style="font-size: 14px; line-height: 21px; font-family: verdana, sans-serif"><img class="blogimg" style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" alt="" src="http://hiphotos.baidu.com/zipand/mpic/item/b0a809d0b2b575259a50276e.jpg" border="0" /></div>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">执行:</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">a.run() 就可用程序来点击那个"弹出窗口"的"确定"按钮了...<br />可用多线程程序用一个线程来处理这类窗口就不妨碍主程序了...</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">另外 一个对 pamie 很有用的 填表类工具 : AiRoboForm.exe</p>
<div style="font-size: 14px; line-height: 21px; font-family: verdana, sans-serif"></div>
<div style="font-size: 14px; line-height: 21px; font-family: verdana, sans-serif"><img class="blogimg" style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" alt="" src="http://hiphotos.baidu.com/zipand/mpic/item/fd97833f78d1ffe7838b1337.jpg" border="0" /></div>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">安装好这个IE工具栏工具后,就可按一下"保存"如上图的"Save"按钮 保存网页表格,然后 鼠标移到 如上图 "Baidu"处停一点时间就出弹出一个子菜单 选择 "edit" 就可看到 那个页面的 表单的 所有名字了 就不用在 源代码里 辛苦的找那么多的 "第一个参数" 也就是说 不用自已找 文本框和列表框名称等了, 你可在那个打开了的 编缉器里看到所有的 要填的框的 "名字"了的只是显示的全是"小写"了, 需要在源文件里看一下第一个字母是否是大写等...pamie是 区分大小写的 AiRoboForm是不区分大小写的...</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">pamie2.0也有不足的地方:</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">下文是一个引自&nbsp;<a style="color: #6fbc4c; text-decoration: none" href="http://yinxl.spaces.live.com/blog/cns%214626e4f8c0bfc0bc%21172.entry">http://yinxl.spaces.live.com/blog/cns!4626e4f8c0bfc0bc!172.entry</a>&nbsp;的 "扩展补丁".</p>
<div style="font-size: 14px; line-height: 21px; font-family: verdana, sans-serif">5月14日</div>
<h4 class="beTitle" style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 0px; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">让PAMIE能轻松控制一个新开的IE窗口</h4>
<div class="bvMsg" style="font-size: 14px; line-height: 21px; font-family: verdana, sans-serif">
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这段时间在写一个WEB的测试程序，根据ZV的推荐，采用了Python实现，因为有个PAMIE的开源包在测试WEB页面时非常好用。但是在使用 PAMIE时发现它的findWindow函数非常难用，导致测试程序很难控制新开的IE窗口，例如HTML：&lt;a href="b.html" target="_blank"&gt;link_content&lt;/a&gt;，这种链接打开的新IE窗口。</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 通过阅读PAMIE的源码也找不到合适的解决办法，只有自己动手啦。我参考了IEC的开源包的方法，自己修改了PAMIE的cPAMIE.py的 PAMIE类的构造函数，修改后的构造函数根据输入的URL地址可以找到当前已经找到的IE窗口，如果没有发现匹配的窗口，那么PAMIE会新建一个窗口 打开该URL。</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp; 下面是修改后的代码：</div>
<div><span style="color: #0000ff; background-color: #ffffff">&nbsp;&nbsp;&nbsp;&nbsp; from win32com.client import Dispatch&nbsp;&nbsp; #需求增加的import语句</span></div>
<div></div>
<div><span style="color: #0000ff; background-color: #ffffff">&nbsp;&nbsp;&nbsp;&nbsp; # 2006-5-10 Modified by YinXianglong to find a opened IE Window. BEGIN<br />&nbsp;&nbsp;&nbsp; def __init__(self, url=None, isFind=False, timeOut=300):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; """ The class instantiation code. When the object is instantiated you can<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pass a starting URL. If no URL is passed then about:blank, a blank<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; page, is brought up.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; parameters:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [url]&nbsp;&nbsp;&nbsp;&nbsp; - url to navigate to initially<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [isFind] - if isFind = True, find a opened IE Window whose LocationURL is equal to url<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [timeOut] - how many 100mS increments to wait, 10 = 1sec, 100=10sec<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; returns:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Nothing<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; """&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.showDebugging = True&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Show debug print lines?<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.colorHighlight = "#F6F7AD"&nbsp;&nbsp;&nbsp;&nbsp; # Set to None to turn off highlighting<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.frameName = None&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # The current frame name or index. Nested frames are<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # supported in the format frame1.frame2.frame3<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.formName = None&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # The current form name or index<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.busyTuner = 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # Number of consecutive checks to verify document is no longer busy.</span></div>
<div><span style="color: #0000ff"><span style="background-color: #ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; find_ok_flag = False<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if isFind and (url != ''):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; clsid='{9BA05972-F6A8-11CF-A442-00A0C90A8F39}'# CLSID for ShellWindows<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ShellWindows = Dispatch(clsid)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; url = url.lower()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for i in range(ShellWindows.Count):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ShellWindows[i].LocationURL.lower().find(url) &gt; -1:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self._ie = ShellWindows[i]<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; find_ok_flag = True<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if not find_ok_flag:&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print "Can't Find the opened IE Window whose LocationURL is equal to url."&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self._ie = DispatchEx('InternetExplorer.Application')<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if url:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self._ie.Navigate(url)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self._ie.Navigate('about:blank')<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self._timeOut = timeOut<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self._ie.Visible = 1<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; self.timer = datetime.datetime.now()&nbsp;&nbsp;&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # 2006-5-10 Modified by YinXianglong to find a opened IE Window.&nbsp;</span>END</span></div>
<div></div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<em style="font-style: italic"><span style="color: #ff0000">&nbsp;其他代码同PAMIE2.0的代码相同。&nbsp;&nbsp;</span></em></div>
<div></div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 下面是测试代码：</div>
<div><span style="color: #0000ff; background-color: #ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; import yxlPAMIE</span></div>
<div><span style="color: #0000ff; background-color: #ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ie = yxlPAMIE.PAMIE("</span>&nbsp;<a style="color: #6fbc4c; text-decoration: none" href="http://172.17.153.171/NewSys/default.aspx"><span style="color: #0000ff; background-color: #ffffff">http://172.17.153.171/NewSys/default.aspx</span>&nbsp;</a><span style="color: #0000ff; background-color: #ffffff">")</span></div>
<div><span style="color: #0000ff; background-color: #ffffff">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print ie.pageGetText()</span>&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 测试结果是显示了已经打开的<a style="color: #6fbc4c; text-decoration: none" href="http://172.17.153.171/NewSys/default.aspx"><span style="color: #0000ff">http://172.17.153.171/NewSys/default.aspx</span>&nbsp;</a>窗口的HTML代码。</div></div>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">附录：网易注册程序代码</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">#coding:gbk<br />import cPAMIE<br />import time<br />import random<br />username = ''.join(random.sample('abcdefghijklmnopqrstuvwxyz0123456789',8))<br />password = '******'<br />zhanghao = '|'.join([username,password])<br />ie= cPAMIE.PAMIE()<br /><br />#打开目标网页<br /><br />ie.navigate ('http://reg.163.com/reg0.shtml')<br /><br />#注意下面所列的 第一个参数如 fistname 等 都是 网页源代码里的 input name="firstname"<br />#里找出来的,不能用 网页上看见的黑体字: "First Name:"<br />#填文本框<br />ie.textBoxSet('username',username)<br /><br />ie.textBoxSet('password','*****')<br />ie.textBoxSet('cpassword','*****')<br /><br />#先择下拉菜单:<br /><br />ie.listBoxSelect('question',unicode('我的自定义问题', 'cp936'))#注意此处编码转换 cp936 可以换成GBK<br />ie.textBoxSet('myQuestion','wodewentishishenme')<br />ie.textBoxSet('answer','wodoubuxihuan')<br />ie.textBoxSet('year','1986')<br />ie.listBoxSelect('month','6')<br />ie.listBoxSelect('day','22')<br />#方形选择框:<br /><br />#ie.checkBoxSet('cxbx',1) #1 2 3 或 * 号等都是 "勾选"的意思 '' 空字符串代表取消选择<br /><br />#圆形选择框: 英语是 radio 做过网页设计就容易知道这些元素的命名了<br />#这里选择 Jazz<br />ie.radioButtonSet("gender","1") # music是这个 选择列表的名字,从网页源代码里找出<br /><br /><br />#最后提交按钮<br /><br />print "请输入验证码 然后提交"<br />#ie.buttonClick("Submit") #用来取代鼠标点击 方便多了<br /><br />i = 0<br />while i&lt;100:<br />&nbsp;&nbsp;&nbsp; pass<br />&nbsp;&nbsp;&nbsp; i = i+1<br />&nbsp;&nbsp;&nbsp; if True == ie.findText(unicode('恭喜', 'gbk')):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">fp = open('163zhanghao.txt','a')<br />fp.write(zhanghao+'\n')<br />fp.close()<br />ie.quit()</p>
<p style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">循环注册</p>
<p id="aeaoofnhgocdbnbeljkmbjdmhbcokfdb-mousedown" style="padding-right: 0px; padding-left: 0px; font-size: 14px; padding-bottom: 0px; margin: 1em 0px 0.5em; color: #444444; line-height: 21px; padding-top: 0px; font-family: verdana, sans-serif">#coding:gbk<br />import cPAMIE<br />import time<br />import random<br />username = ''.join(random.sample('abcdefghijklmnopqrstuvwxyz0123456789',8))<br />password = 'wokao1'<br />zhanghao = '|'.join([username,password])<br />i = 0<br />while i&lt;1000:<br />&nbsp;&nbsp;&nbsp; ie= cPAMIE.PAMIE()<br />&nbsp;&nbsp;&nbsp; ie.navigate ('https://passport.baidu.com/?reg')<br />&nbsp;&nbsp;&nbsp; ie.textBoxSet('username',username)<br />&nbsp;&nbsp;&nbsp; ie.textBoxSet('loginpass','*****')<br />&nbsp;&nbsp;&nbsp; ie.textBoxSet('verifypass','*****')<br />&nbsp;&nbsp;&nbsp; ie.radioButtonSet("sex","1")&nbsp;<br />&nbsp;&nbsp;&nbsp; ie.textBoxSet("email",username+'@msn.cn')<br />&nbsp;&nbsp;&nbsp; i = 0<br />&nbsp;&nbsp;&nbsp; while i&lt;1000:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pass<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i = i+1<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if True == ie.findText(unicode('恭喜', 'gbk')):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break<br />&nbsp;&nbsp;&nbsp; fp = open('163zhanghao.txt','a')<br />&nbsp;&nbsp;&nbsp; fp.write(zhanghao+'\n')<br />&nbsp;&nbsp;&nbsp; fp.close()<br />&nbsp;&nbsp;&nbsp; ie.quit()<br />&nbsp;&nbsp;&nbsp; i = i+1<br /><br />__________________________________________________再补充一个：<br />import winGuiAuto<br /># 获取得的hwnd是一个列表<br />hwnd = winGuiAuto.findTopWindows("Windows Internet Explorer")<br /># 获取得的control_list是一个列表，每个元素又是一个列表，这个列表中第一个是句柄,第二个是文本，第三个是窗口类型<br />control_list=winGuiAuto.dumpWindow(hwnd[0])<br />for control_item in control_list:<br />if control_item[1]='OK':<br /># 单击确定OK<br />winGuiAuto.clickButton(control_item[0])<br /><br />这里每个contrl item有三个成员，第一个是系统id号，第二个是显示出来的文字，第三个是类型，具体可以print出来看看。</p><img src ="http://www.blogjava.net/pts/aggbug/350350.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/pts/" target="_blank">pts</a> 2011-05-16 21:51 <a href="http://www.blogjava.net/pts/archive/2011/05/16/350350.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>【转】PAMIE:点击网页中的弹出窗口的按钮</title><link>http://www.blogjava.net/pts/archive/2011/05/16/350349.html</link><dc:creator>pts</dc:creator><author>pts</author><pubDate>Mon, 16 May 2011 13:22:00 GMT</pubDate><guid>http://www.blogjava.net/pts/archive/2011/05/16/350349.html</guid><wfw:comment>http://www.blogjava.net/pts/comments/350349.html</wfw:comment><comments>http://www.blogjava.net/pts/archive/2011/05/16/350349.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/pts/comments/commentRss/350349.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/pts/services/trackbacks/350349.html</trackback:ping><description><![CDATA[<p id="aeaoofnhgocdbnbeljkmbjdmhbcokfdb-mousedown" style="margin-top: 0px; margin-right: 0px; margin-bottom: 14px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-size: 14px; line-height: 20px; text-align: justify; font-family: arial, helvetica, sans-serif, verdana, 宋体; ">From：<span  style="font-family: Simsun; line-height: normal; font-size: medium; "><a href="http://it.chinawin.net/softwaredev/article-40a.html">http://it.chinawin.net/softwaredev/article-40a.html</a></span></p>
<p id="aeaoofnhgocdbnbeljkmbjdmhbcokfdb-mousedown" style="margin-top: 0px; margin-right: 0px; margin-bottom: 14px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-size: 14px; line-height: 20px; text-align: justify; font-family: arial, helvetica, sans-serif, verdana, 宋体; ">在我们登录网页的时候，如果某账户刚刚登录，系统会有如下提示：</p>
<p id="" style="margin-top: 0px; margin-right: 0px; margin-bottom: 14px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-size: 14px; line-height: 20px; text-align: justify; font-family: arial, helvetica, sans-serif, verdana, 宋体; ">本文就是讲述如何用PAMIE处理这种POPUP window。主要是如何选择POPUP window以及点击上面的"OK"或者"Cancel"按钮。对弹出窗口的处理，主要都在winGuiAuto.py中。</p>
<p id="" style="margin-top: 0px; margin-right: 0px; margin-bottom: 14px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; font-size: 14px; line-height: 20px; text-align: justify; font-family: arial, helvetica, sans-serif, verdana, 宋体; ">import winGuiAuto<br style="margin-bottom: 8px; " />
# 获取得的hwnd是一个列表<br style="margin-bottom: 8px; " />
hwnd = winGuiAuto.findTopWindows("Windows Internet Explorer")<br style="margin-bottom: 8px; " />
# 获取得的control_list是一个列表，每个元素又是一个列表，这个列表中第一个是句柄,第二个是文本，第三个是窗口类型<br style="margin-bottom: 8px; " />
control_list=winGuiAuto.dumpWindow(hwnd[0])<br style="margin-bottom: 8px; " />
for control_item in control_list:<br style="margin-bottom: 8px; " />
if control_item[1]='OK':<br style="margin-bottom: 8px; " />
# 单击确定OK<br style="margin-bottom: 8px; " />
winGuiAuto.clickButton(control_item[0])<br style="margin-bottom: 8px; " />
</p>
<span  style="font-family: arial, helvetica, sans-serif, verdana, 宋体; font-size: 14px; line-height: 20px; ">作者：Shane 本文版权归作者和博客园共有，欢迎转载，但未经作者同意必须保留此段声明，且在文章页面明显位置给出原文连接，否则保留追究法律责任的权利。</span>
<img src ="http://www.blogjava.net/pts/aggbug/350349.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/pts/" target="_blank">pts</a> 2011-05-16 21:22 <a href="http://www.blogjava.net/pts/archive/2011/05/16/350349.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[1]  Django笔记：Django 入门</title><link>http://www.blogjava.net/pts/archive/2010/05/30/322276.html</link><dc:creator>pts</dc:creator><author>pts</author><pubDate>Sun, 30 May 2010 06:48:00 GMT</pubDate><guid>http://www.blogjava.net/pts/archive/2010/05/30/322276.html</guid><wfw:comment>http://www.blogjava.net/pts/comments/322276.html</wfw:comment><comments>http://www.blogjava.net/pts/archive/2010/05/30/322276.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/pts/comments/commentRss/322276.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/pts/services/trackbacks/322276.html</trackback:ping><description><![CDATA[<pre><span class="k">from</span> <span class="nn">django.db</span> <span class="k">import</span> <span class="n">models</span><br />
<br />
<br />
<br />
<span class="k">class</span> <span class="nc">Poll</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span><br />
<br />
<span class="n">question</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">CharField</span><span class="p">(</span><span class="n">max_length</span><span class="o">=</span><span class="mf">200</span><span class="p">)</span><br />
<br />
<span class="n">pub_date</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">DateTimeField</span><span class="p">(</span><span class="s">'date published'</span><span class="p">)</span><br />
<br />
<br />
<br />
<span class="k">class</span> <span class="nc">Choice</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span><br />
<br />
<span class="n">poll</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">ForeignKey</span><span class="p">(</span><span class="n">Poll</span><span class="p">)</span><br />
<br />
<span class="n">choice</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">CharField</span><span class="p">(</span><span class="n">max_length</span><span class="o">=</span><span class="mf">200</span><span class="p">)</span><br />
<br />
<span class="n">votes</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">IntegerField</span><span class="p">()</span><br />
<br />
<br />
<br />
</pre>
安装Django<br />
<br />
<h2>建议安装python2.5及以上版本，但不建议使用python3.0。</h2>
数据库如果使用sqllite，python已经内建，不需另行安装，如果需要使用myslq或其他数据库，需要自行安装。<br />
<br />
接下来安装Django（在widnwos下）：<br />
1、从http://www.djangoproject.com/download/下载Django<br />
2、在windwos下使用python setup.py install 安装（我原想使用python setup.py develop安装，没成功），前提是设置好python环境和已安装setuptools。<br />
3、将python安装目录下lib\site-packages\django\bin\django-admin.py 复制到python安装目录下的\scripts\目录。<br />
<br />
下面可以测试一下，启动cmd窗口：<br />
C:\Documents and Settings\Administrator&gt;python<br />
&gt;&gt;&gt; import django<br />
&gt;&gt;&gt; django.VERSION<br />
(1, 2, 0, 'rc', 1)<br />
<br />
安装OK。开始创建第一个project吧。<br />
<br />
1、选定一个目录，启动cmd窗口：<br />
F:\temp&gt;django-admin.py startproject mysite2<br />
F:\temp&gt;<br />
这将在当前目录下新建一个project，名字为mysite2（注意不要使用"django"等保留字作为project名称），目录结构为：<br />
<br />
2010-05-30&nbsp; 13:29&nbsp;&nbsp;&nbsp; &lt;DIR&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .<br />
2010-05-30&nbsp; 13:29&nbsp;&nbsp;&nbsp; &lt;DIR&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ..<br />
2010-05-30&nbsp; 13:29&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 557 manage.py<br />
2010-05-30&nbsp; 13:29&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3,387 settings.py<br />
2010-05-30&nbsp; 13:29&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 561 urls.py<br />
2010-05-30&nbsp; 13:29&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0 __init__.py<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4 个文件&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4,505 字节<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2 个目录 29,717,716,992 可用字节<br />
<ul class="simple">
    <li><tt class="docutils literal"><span class="pre">__init__.py</span></tt>:暂时是空的，标识这个目录是一个python package。</li>
    <li><tt class="docutils literal"><span class="pre">manage.py</span></tt>: Django的命令行工具集，使用方法：python manage.py ***<br />
    </li>
    <li><tt class="docutils literal"><span class="pre">settings.py</span></tt>: project 的配置文件</li>
    <li><tt class="docutils literal"><span class="pre">urls.py</span></tt>: project的url路径管理配置文件</li>
</ul>
先了解这么多吧，详细的文件内容单独再说。<br />
<br />
2、启动http server:<br />
F:\temp\mysite2&gt;python manage.py runserver<br />
Validating models...<br />
0 errors found<br />
<br />
Django version 1.2 rc 1, using settings 'mysite2.settings'<br />
Development server is running at http://127.0.0.1:8000/<br />
Quit the server with CTRL-BREAK.<br />
<br />
打开web browser，输入地址http://127.0.0.1:8000/，可以看到server已经启动了。当然，如果你希望换一个端口，可以使用：<span style="font-family: monospace;"><br />
</span>python manage.py runserver 端口号<br />
<br />
3、接着配置database：<br />
<p><span style="font-family: monospace;">打开</span><tt class="docutils literal"><span class="pre">settings.py<span style="font-family: sans-serif;">，在database节点下：</span></span></tt></p>
<ul>
    <li>
    <p class="first"><a class="reference external" href="http://docs.djangoproject.com/en/1.2/ref/settings/#setting-ENGINE"><tt class="xref docutils literal"><span class="pre">ENGINE</span></tt></a> <span style="font-family: monospace;">数据库引擎名称，可以是</span><tt class="docutils literal"><span class="pre">'django.db.backends.postgresql_psycopg2'</span></tt>或
    <tt class="docutils literal"><span class="pre">'django.db.backends.mysql'</span></tt> 或
    <tt class="docutils literal"><span class="pre">'django.db.backends.sqlite3'</span></tt></p>
    </li>
    <li>
    <p><a class="reference external" href="http://docs.djangoproject.com/en/1.2/ref/settings/#setting-NAME"><tt class="xref docutils literal"><span class="pre">NAME</span></tt></a>&nbsp; 数据库名称， 如果使用sqlite，这里就是db文件绝对路径，比如f:/temp/mysite/data.db</p>
    </li>
    <li>
    <p class="first"><a class="reference external" href="http://docs.djangoproject.com/en/1.2/ref/settings/#setting-USER"><tt class="xref docutils literal"><span class="pre">USER</span></tt></a> 数据库用户名，sqlite不需要</p>
    </li>
    <li>
    <p class="first"><a class="reference external" href="http://docs.djangoproject.com/en/1.2/ref/settings/#setting-PASSWORD"><tt class="xref docutils literal"><span class="pre">PASSWORD</span></tt></a> 密码，sqlite不需要</p>
    </li>
    <li>
    <p class="first"><a class="reference external" href="http://docs.djangoproject.com/en/1.2/ref/settings/#setting-HOST"><tt class="xref docutils literal"><span class="pre">HOST</span></tt></a> 数据库主机ip，sqlite不需要</p>
    </li>
</ul>
<p>建议使用sqlite。如果使用其他如PostgerSQL、MySQL等，在配置之前要确保先在数据库中已建立相关项目。<br />
</p>
在setting.py中的INSTALLED_APPS节点下，默认有以下一个APP：<br />
&nbsp;&nbsp;&nbsp; 'django.contrib.auth',用户认证<br />
&nbsp;&nbsp;&nbsp; 'django.contrib.contenttypes',内容管理?<br />
&nbsp;&nbsp;&nbsp; 'django.contrib.sessions',session控制<br />
&nbsp;&nbsp;&nbsp; 'django.contrib.sites',多site管理<br />
如果用不到该app，可以注释掉，这将不在database中建立相关管理tables。然后使用：<br />
python manage.py syncdb<br />
建立相应的tables。<br />
<br />
4、在mysite2目录下，新建一个自己的app：<br />
python manage.py startapp polls<br />
将新建一个polls目录，内容如下：<br />
2010-05-30&nbsp; 14:07&nbsp;&nbsp;&nbsp; &lt;DIR&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .<br />
2010-05-30&nbsp; 14:07&nbsp;&nbsp;&nbsp; &lt;DIR&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ..<br />
2010-05-30&nbsp; 14:07&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 60 models.py<br />
2010-05-30&nbsp; 14:07&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 537 tests.py<br />
2010-05-30&nbsp; 14:07&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 27 views.py<br />
2010-05-30&nbsp; 14:07&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0 __init__.py<br />
<br />
5、创建models：<br />
编辑models.py,内容如下：<br />
<pre><span class="k">from</span> <span class="nn">django.db</span> <span class="k">import</span> <span class="n">models</span><br />
<br />
<span class="k">class</span> <span class="nc">Poll</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span><br />
<br />
<span class="n">question</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">CharField</span><span class="p">(</span><span class="n">max_length</span><span class="o">=</span><span class="mf">200</span><span class="p">)</span><br />
<br />
<span class="n">pub_date</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">DateTimeField</span><span class="p">(</span><span class="s">'date published'</span><span class="p">)</span><br />
<br />
<span class="k">class</span> <span class="nc">Choice</span><span class="p">(</span><span class="n">models</span><span class="o">.</span><span class="n">Model</span><span class="p">):</span><br />
<br />
<span class="n">poll</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">ForeignKey</span><span class="p">(</span><span class="n">Poll</span><span class="p">)</span><br />
<br />
<span class="n">choice</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">CharField</span><span class="p">(</span><span class="n">max_length</span><span class="o">=</span><span class="mf">200</span><span class="p">)</span><br />
<br />
<span class="n">votes</span> <span class="o">=</span> <span class="n">models</span><span class="o">.</span><span class="n">IntegerField</span><span class="p">()</span><br />
<br />
这里有两个model，Poll和Choice，还存在一个one Poll to many Choice关系。<br />
<br />
在setting.py 中将polls 加入到installed app 节点中，然后使用python manage.py syncdb 将在database中新建相应的tables。<span style="font-family: sans-serif;">table name 分别是：<br />
<br />
polls_poll,polls_choice。<br />
<br />
当然还有其他一些manage command:<br />
<br />
</span></pre>
<ul class="simple">
    <li><a class="reference external" href="http://docs.djangoproject.com/en/dev/ref/django-admin/#djadmin-validate"><tt class="xref docutils literal"><span class="pre">python</span> <span class="pre">manage.py</span> <span class="pre">validate</span></tt></a> -- 校验model内容是否正确<br />
    </li>
    <li><a class="reference external" href="http://docs.djangoproject.com/en/dev/ref/django-admin/#djadmin-sqlcustom"><tt class="xref docutils literal"><span class="pre">python</span> <span class="pre">manage.py</span> <span class="pre">sqlcustom</span> <span class="pre">polls</span></tt></a> -- 输出polls app中的model相关的sql相关语句<br />
    </li>
    <li><a class="reference external" href="http://docs.djangoproject.com/en/dev/ref/django-admin/#djadmin-sqlclear"><tt class="xref docutils literal"><span class="pre">python</span> <span class="pre">manage.py</span> <span class="pre">sqlclear</span> <span class="pre">polls</span></tt></a> -- 输出删除table的相关sql</li>
    <li><a class="reference external" href="http://docs.djangoproject.com/en/dev/ref/django-admin/#djadmin-sqlindexes"><tt class="xref docutils literal"><span class="pre">python</span> <span class="pre">manage.py</span> <span class="pre">sqlindexes</span> <span class="pre">polls</span></tt></a> -- 输出建立index的相关sql</li>
    <li><a class="reference external" href="http://docs.djangoproject.com/en/dev/ref/django-admin/#djadmin-sqlall"><tt class="xref docutils literal"><span class="pre">python</span> <span class="pre">manage.py</span> <span class="pre">sqlall</span> <span class="pre">polls</span></tt></a> -- <span style="font-family: monospace;">是</span><a class="reference external" href="http://docs.djangoproject.com/en/dev/ref/django-admin/#djadmin-sql"><tt class="xref docutils literal"><span class="pre">sql</span></tt></a>, <a class="reference external" href="http://docs.djangoproject.com/en/dev/ref/django-admin/#djadmin-sqlcustom"><tt class="xref docutils literal"><span class="pre">sqlcustom</span></tt></a>, and
    <a class="reference external" href="http://docs.djangoproject.com/en/dev/ref/django-admin/#djadmin-sqlindexes"><tt class="xref docutils literal"><span class="pre">sqlindexes</span></tt></a> 输出内容的组合<br />
    </li>
</ul>
<pre>6、使用django shell：<br />
<br />
python manage.py shell<br />
<br />
这个cmd背后做了两件事：一是将mysite2加入到sys.path中去；二是新建了<tt class="docutils literal"><span class="pre">DJANGO_SETTINGS_MODULE环境变量，可以引用settings.py中的配置内容。<br />
<br />
接下来就可以测试了。<br />
<br />
</span></tt></pre>
<img src ="http://www.blogjava.net/pts/aggbug/322276.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/pts/" target="_blank">pts</a> 2010-05-30 14:48 <a href="http://www.blogjava.net/pts/archive/2010/05/30/322276.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转] 复杂的Unicode，疑惑的Python</title><link>http://www.blogjava.net/pts/archive/2009/07/20/287506.html</link><dc:creator>pts</dc:creator><author>pts</author><pubDate>Mon, 20 Jul 2009 10:44:00 GMT</pubDate><guid>http://www.blogjava.net/pts/archive/2009/07/20/287506.html</guid><wfw:comment>http://www.blogjava.net/pts/comments/287506.html</wfw:comment><comments>http://www.blogjava.net/pts/archive/2009/07/20/287506.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/pts/comments/commentRss/287506.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/pts/services/trackbacks/287506.html</trackback:ping><description><![CDATA[<h2 class="date-header">猛然间看到这篇文章，才发现原来自己理解的uniocde还是表面，这篇文章又说明了很多深层次的内容，值得一看。<br />
</h2>
From：http://jawahh.sjtubbs.org/2008/07/unicodepython.html<br />
<br />
<h2 class="date-header">2008年7月21日</h2>
<a style="width: 20px; height: 20px; text-indent: 20px; background-repeat: no-repeat; background-image: url(/CuteSoft_Client/CuteEditor/Load.ashx?type=image&amp;file=anchor.gif);" name="1566199598866648015"></a>
<h3 class="post-title entry-title">
<a href="http://jawahh.sjtubbs.org/2008/07/unicodepython.html">复杂的Unicode，疑惑的Python</a>
</h3>
<div class="post-body entry-content">
<p>Python 3000决定采用Unicode作为字符的默认编码。这不是什么新闻了，也是国际化的大势所趋。但实际上似乎没有那么简单。最近python-dev邮件列表吵的一个问题就很有意思。</p>
<p>7月2日，一个叫Jeroen Ruigrok van der Werven的人以<a href="http://mail.python.org/pipermail/python-dev/2008-July/080892.html"><font color="#0000ff">UCS2/UCS4 default </font></a>为
标题说了问题。Python虽然采用unicode作为默认字符，但语言内部用什么方法表示unicode字符串并没有一致的规定。在编译的时候可以选择
用UCS2或者UCS4编码。作者说，随着unicode中的CJK象形字扩展B（CJK ideographs extension
B)已经加入最新的unicode规范，扩展C已经在投票表决阶段，扩展D已经在开发，使用UCS2编码已经不能满足预期未来的应用了。所以应该默认使用
UCS4编码。而且作者认为允许UCS2和UCS4两种编码会产生编程一致性的问题。比如，在用UCS2编码的python 3中：</p>
<div style="border: 1px solid gray; margin: 20px 0px 10px; padding: 4px; overflow: auto; font-size: 8pt; width: 97.5%; cursor: text; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4; max-height: 200px;">
<div style="border-style: none; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">&gt;&gt;&gt; len(<span style="color: #006080;">"\N{MUSICAL SYMBOL G CLEF}"</span>)</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">2</pre>
</div>
</div>
而在用USC4编码中的python 3中：
<div style="border: 1px solid gray; margin: 20px 0px 10px; padding: 4px; overflow: auto; font-size: 8pt; width: 97.5%; cursor: text; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4; max-height: 200px;">
<div style="border-style: none; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">&gt;&gt;&gt; len(<span style="color: #006080;">"\N{MUSICAL SYMBOL G CLEF}"</span>)</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">1</pre>
</div>
</div>
<p>然后这个问题就引起了一场大混战。这个问题到底是什么问题呢？到底为什么会允许那么奇怪的事情发生：同一个字符串在不同的编译版本中长度不一样呢？其实这个问题根植在unicode复杂的规范和历史中。</p>
<p>Unicode的一个中文名字叫&#8220;万国码&#8221;。这个翻译很明确指出了Unicode的任务，为人类使用的文字都编一个号码，解决他们在计算机中共存的
问题，消除计算机世界里面万码奔腾的兼容性问题。现在unicode
5.1规范已经于2008-04-04发布，而且也确实很大部分消除了计算机世界里面兼容问题，成为了事实规范。现在哪个稍大的新程序不支持
Unicode，是说不过去的。不过这不表示unicode里面没有什么犄角旮旯影响着大家的使用。</p>
<p>第一个问题是，unicode到底要给什么编号？对中文来说，当然是给字编号——在中文里面是这样，但unicode并不是中文编码，这个世界的书
写文字五花八门，中文概念里面的字在其他书写文字里面并不一定存在。在这里要澄清的两个概念是glyph和character。Glyph是文字的图像，
是我们书写的最小单元，是屏幕上看到的，打印机上打出来的最小单元。Character是一种逻辑上和语言学上的描述，它并不完全等同于Glyph。
Glyph和Character之间有多种组合发生。一种情况是一个Glyph代表多个character。举中文里面的多音字说明，比如&#8220;没&#8221;字，它有
两个读音，而且意义完全不一样，但只有一个表现形式。&#8220;没&#8221;代表着一个glyph，代表着两个character。如果再加上日语和韩语，这种同一个
glyph却有多个character的情况就更多了。还有一个情况是多个character才能组成一个glyph。主要是一些字母的音调问题。中文里
面也有这个问题，比如&#8220;e&#8221;和&#8220;ˊ&#8221;这两个character可以组成一个glyph&#8220;&#233;&#8221;。还有一种我们不太熟悉的情况是多个glyph只是一个
character，主要出现在阿拉伯文中。在阿拉伯文中，一个字母在不同的书写情况下可能有不同的表现形式（glyph）。还有一种情况
是，character没有对应的glyph，比如我们常见的回车符。事实上，unicode并没有给出一个标准的说法说明到底给什么编号，它走的是务实
主义。Unicode大致可以说的是给character编号，但也会照顾到各种语言的现实，会给glyph编号。对于编程，一个简单的计算字符串长度就
会发生歧义。到底我们是计算unicode字符串的character数量还是glyph数量？在ascii编码中没有这个问题，因为它的
character和glyph是统一的。Unicode解决这个问题的方法是不仅仅给character编号，还给每个character编订了
unicode character
property。软件可以计算character数量，也可以根据character查询属性，用于计算和显示glyph。</p>
<p>第二个问题是，unicode到底打算使用多少个编号？现在的Unicode使用了21bit的数字去编号。目前看来21bit在可预见的将来是足
够使用的——除非人类发现了外星人文明，需要为他们编号。现在的unicode编号从0x0-0x10FFFF分为17个Plane，编号从0-16。从
0x0-0xFFFD为BMP（Basic Multilingual
Plane)，也就是前16bit，集中了大多现代书写系统；从0x10000-0x1FFFD为SMP（Supplementary
Mulitilingual
Plane），包括了大多在历史上曾经使用的书写系统；从0x20000-0x2FFFD为SIP（Supplementary
Ideographic Plane），用于每年新增加的象形文字；然后11个plane尚未使用；Plane
14（0xE0000-0xEFFFD）为SSP（Supplementary Special-Purpose
Plane），存放一些争议性比较大的字符（语义上比较模糊或者会给文字处理带来麻烦），使用这些字符都需要多加小心；后面两个Plane
15（0xF0000-0xFFFFD)和Plane
16（0x100000-0x10FFFD）为保留区，任何人都可以私自定义这个区域，当然Unicode规范也不保证这些区域可以在异构系统上顺利交
换。还有一个特殊字符编号0xFEFF是BOM（Byte Order Mark），包括它对判断Byte
Order有特殊用途，所以它的另外一面0xFFFE也就被规定为非Unicode字符（也就是为什么Plane的结束都是0xFFFD的原因）。上面的
说法看起来没有什么太大的问题，但这不是故事的全部。最开始的Unicode只打算用16bit的数字，也就是现在的BMP去实现它的目的，这个跟当年的
兼容和效率考量有关。但这显然是不够的，尤其对于庞大的CJK象形文字——至今Unicode已经包含了7万多个CJK象形文字。这是个不幸的历史。所以
早期的Unicode实现中，并没有考虑到16bit以外的问题。比如大量使用的Windows和Java构建的系统。Unix系统倒是塞翁失马焉知非
福，对Unicode的支持比较晚，所以大多都是用32bit去表示21bit的unicode编号。历史的悲剧就这么产生了，虽然都是Unicode，
但历史遗留系统和现代系统的不同表示还是给所有希望实现Portability的应用带来尴尬的处境。Python的UCS2/UCS4问题就是其中之
一，但这不是造成这个问题的全部原因，还有下一个原因。</p>
<p>第三个问题是，unicode到底是什么？这是个很严肃的问题。Unicode只是字符编号，字符编号的属性，以及相关说明的集合。Unicode
不是平常所说的编码（Encoding）。Unicode规范只是规定了每个字符的编号（Code
Point)。虽然它是为计算机设计的规范，但这个编号和计算机如何存储，如何表示这些字符没有直接关系。在这一层，叫做CCS（Coded
Character
Set）。理论上如何表示Unicode字符是应用程序的自由，喜欢怎么表示就怎么表示，只要你的表示方法能找到字符对应的Code
Point就行。当然，大家不能让这种混乱出现，所以有了CEF（Character Encoding
Form）这一层。这一层关注的是在计算机理论上如何从数字到映射Code
Point，也就是如何在8bit为单位的计算机系统中表示21bit的Unicode Code
Point。其中UCS2，UCS4，UTF32，UTF16，UTF8等等都是实际上使用的方案。理论上映射和实践上映射不完全一样，实践上还要考虑异
构系统的可交换特性，也就是解决大小端问题的CES（Character Encoding
Scheme）。所以又会有UTF32-LE，UTF32-BE，UTF16-BE，UTF16-LE，UTF8（对的，UTF8是CEF，也是
CES）。还有最后一层，是TES（Transfer Encoding
Syntax）。这一层解决的问题是在特定传输环境中的编码问题，比如把UTF8字符串再用base64编码用于电子邮件传输。跟Python有关的是
CEF这一层。前面说过，历史上Unicode的code
point是16bit的，所以无论是UCS2，UCS4，UTF32，UTF16，UTF8都可以相安无事。对于前四者来说，都是一个code
unit对应一个code point（code
unit是CEF的最小单位，对于UCS4和UTF32是32bit，对于UCS2和UTF16是16bit，对于UTF8是8bit）；对于UTF8来
说是1到3个code unit对应一个code
point。这时候的UCS4和UTF32是等价的，UCS2和UTF16是等价的。后来unicode扩展为21位了。对于UCS4和UTF32来说，
还是一个code unit对应一个code point，对应用程序来说变化不大。而对于UTF8来说，变成了1-4个code
unit对应一个code point（为什么是扩展到21bit这么奇怪的数字呢？我猜测是为了UTF8的效率，因为UTF8中4个code
unit正好最多可以表示21bit的code
point），因为UTF8本来就是长度可变的编码，问题也不大。但对UCS2和UTF16来说，问题就比较头疼了。UCS2和UTF16本来是固定长度
编码，但现在无论如何也不可能用16bit的存储表示21bit的code
point。UCS2和UTF16在这里就分道扬镳了。UCS2的处理方法很暴力，只保留低16位信息，忽略高5位的信息，也就是只兼容BMP中的
code point。而UTF16就变成了可变长度编码。解决方法是在BMP中划分出两个保留区域，分别是0xD800-0xDBFF的High
Surrogate Area和0xDC00-0xDFFF的Low Surrogate
Area。编码方案是，假如有一个大于0xFFFF的code
point是X，那么让Y=X-0x10000；Y显然是介于0x00和0xFFFFF之间的20bit数据（这也就是为什么unicode虽然扩展到
21bit，但只有17个plane——理论上21bit可以表示32个plane）。假如Y这个数字的分隔为高10bit和低10bit（假如是
xxxxxxxxxxyyyyyyyyyy)，那么X的UTF16编码110110xxxxxxxxxx
110111yyyyyyyyyy，正好落在Surrogate Area里面。就这样UTF16变成了长度可变编码。用Python表示就是：</p>
<div style="border: 1px solid gray; margin: 20px 0px 10px; padding: 4px; overflow: auto; font-size: 8pt; width: 97.5%; cursor: text; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4; max-height: 200px;">
<div style="border-style: none; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: white;">high = ((X-0x10000)&gt;&gt;10)&amp;0x3FF+0xD800</pre>
<pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; font-size: 8pt; width: 100%; color: black; line-height: 12pt; font-family: consolas,'Courier New',courier,monospace; background-color: #f4f4f4;">low = (X-0x10000)&amp;0x3FF+0xDC00</pre>
</div>
</div>
<p>但对使用UTF16编码的程序来说，一个字符串的code point数量（也就是unicode character的数量）和code unit的数量不再是恒等的——如果代码里面曾经简单的恒等这两个数量，代码就出错了。</p>
<p>回到Python的问题上，由于历史原因，现有的系统即有使用UCS2（Windows，Java——Java从1.5开始改为支持UTF16）也
有使用UCS4（Unix/Linux)的。为了在各个系统上的最大兼容性，Python的Unicode字符串在内存中的表示方式一直都有两种，在编译
的时候指定（有--with-wide-unicode的时候用UCS4)。对于同一个不在BMP范围内的字符"\N{MUSICAL SYMBOL
G CLEF}"，UCS4的Python内部表示成一个UCS4 code unit，计算长度的时候自然就是等于一，因为code
unit的数量和code
point的数量是恒等的；但UCS2的Python为了不丢失信息，首先用UTF16的编码方式把不在BMP范围内的字符编码成两个UTF16
code unit，但计算长度的时候，返回的是code unit的数量，而不是code
point的数量！所以邮件列表上有人说，UCS2的Python用UTF16的编码处理了字符输入，又按照UCS2的方式在内部使用。UCS2和
UTF16之间的混淆不清大概就是这个问题的根源。</p>
<p>平心而论，UTF16并不是一个糟糕的编码。它的优点是对于大多常用的字符（在BMP范围内的）更紧凑，无论是分割字符，计算字符，都和UTF32
一样。但问题就在于不是BMP范围内的字符。要以code
point为单位处理这些字符的UTF16编码需要跟复杂和低效的算法，比如随机访问字符串中的某个字符从O(1)变成了O(N)。Java也是有这个问
题的语言，它曾经是UCS2，但从1.5开始，增加了一套处理UTF16字符的API（String.codePointCount /
String.codePointAt / String.codePointBefore /
String.offsetByCodepoints）。所以在Java中，原来的代码会保持原来的UCS2处理方式，当你要使用超过BMP范围的字符
时，可以使用新的API处理；这样在兼容和正确处理之间找一个妥协方案。但Python由于用了两种内部表示方案，问题就变得更复杂。程序员不仅要注意到
code unit和code point的区别，还要注意到UCS4和UCS2中的code unit区别。</p>
<p>邮件列表中争吵到最后的结果大概是在文档中增加对这些区别的说明，同时增加一套新的API用于按照code
point为单位处理（假如有人做的话），并不改变旧有的API的行为(isalpha之类的API可以改变，因为不影响兼容性）。跟现实世界
javascript:void(0)一样，历史问题总是不能完美解决的。</p>
<p>最后推荐一本书，O'REILLY出版的<a href="http://www.amazon.com/dp/0596102429">Fonts &amp; Encoding</a>，前半部分关于unicode的讨论可以学到不少关于unicode的知识。</p>
</div>
<div class="post-footer-line post-footer-line-1"><span class="post-timestamp">
时间：
<a class="timestamp-link" href="http://jawahh.sjtubbs.org/2008/07/unicodepython.html" rel="bookmark" title="permanent link"><abbr class="published" title="2008-07-21T01:27:00+08:00">1:27:00 上午</abbr></a>
</span>
<span class="post-labels">
标签：
<a href="http://jawahh.sjtubbs.org/search/label/encoding" rel="tag">encoding</a>,
<a href="http://jawahh.sjtubbs.org/search/label/python" rel="tag">python</a>
</span>
<span class="post-comment-link">
</span>
<span class="post-backlinks post-comment-link">
</span>
<span class="post-icons">
<span class="item-action">
<a href="http://www.blogger.com/email-post.g?blogID=3957601477414214759&amp;postID=1566199598866648015" title="以电子邮件发送帖子">
<img alt="" class="icon-action" src="http://www.blogger.com/img/icon18_email.gif" />
</a>
</span>
<span class="item-control blog-admin pid-978431174">
<a href="http://www.blogger.com/post-edit.g?blogID=3957601477414214759&amp;postID=1566199598866648015" title="修改帖子">
<img alt="" class="icon-action" src="http://www.blogger.com/img/icon18_edit_allbkg.gif" height="18" width="18" /></a><a href="http://www.blogger.com/post-edit.g?blogID=3957601477414214759&amp;postID=1566199598866648015" title="修改帖子">
</a>
</span>
</span>
</div>
<img src ="http://www.blogjava.net/pts/aggbug/287506.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/pts/" target="_blank">pts</a> 2009-07-20 18:44 <a href="http://www.blogjava.net/pts/archive/2009/07/20/287506.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]python 中文乱码 问题深入分析</title><link>http://www.blogjava.net/pts/archive/2009/06/25/284124.html</link><dc:creator>pts</dc:creator><author>pts</author><pubDate>Thu, 25 Jun 2009 07:59:00 GMT</pubDate><guid>http://www.blogjava.net/pts/archive/2009/06/25/284124.html</guid><wfw:comment>http://www.blogjava.net/pts/comments/284124.html</wfw:comment><comments>http://www.blogjava.net/pts/archive/2009/06/25/284124.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/pts/comments/commentRss/284124.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/pts/services/trackbacks/284124.html</trackback:ping><description><![CDATA[<p class="p0"><span><a href="http://blog.csdn.net/kiki113/archive/2009/04/10/4062063.aspx">From</a>:到现在还是不太明白python的乱码解决之道，很应该仔细看看<br />
</span></p>
<p class="p0"><span><br />
</span></p>
<p class="p0"><span>在本文中，以'哈'来解释作示例解释所有的问题，&#8220;哈&#8221;的各种编码如下：</span></p>
<p class="p0"><span>&nbsp;&nbsp;1.&nbsp;</span><span>UNICODE (UTF8-16)，C854；</span></p>
<p class="p0"><span>&nbsp;&nbsp;2． UTF-8，E59388；</span></p>
<p class="p0"><span>&nbsp;&nbsp;3． GBK，B9FE。</span></p>
<h4>一、python中的str和unicode</h4>
<p class="p0">一直以来，python中的中文编码就是一个极为头大的问题，经常抛出编码转换的异常，python中的str和unicode到底是一个什么东西呢？</p>
<p class="p0">在python中提到unicode，一般指的是unicode对象，例如'哈哈'的unicode对象为</p>
<p class="p0">u'\u54c8\u54c8'</p>
<p class="p0">而str，是一个字节数组，这个字节数组表示的是对unicode对象编码(可以是utf-8、gbk、cp936、GB2312)后的存储的格式。这里它仅仅是一个字节流，没有其它的含义，如果你想使这个字节流显示的内容有意义，就必须用正确的编码格式，解码显示。</p>
<p class="p0"><span style="font-family: 宋体;">例如：</span></p>
<p class="p0"><span style="font-family: 宋体;"><img src="http://p.blog.csdn.net/images/p_blog_csdn_net/kiki113/EntryImages/20090409/str_unicode.jpg" alt="python 字符串和unicode" height="225" width="341" /></span></p>
<p class="p0"><span><span style="font-family: 宋体;">对于unicode对象哈哈进行编码，编码成
一个utf-8编码的str－s_utf8,s_utf8就是是一个字节数组，存放的就是'\xe5\x93\x88\xe5\x93\x88'，但是这
仅仅是一个字节数组，如果你想将它通过print语句输出成哈哈，那你就失望了，为什么呢？</span></span></p>
<p class="p0"><span><span style="font-family: 宋体;">因为print语句它的实现是将要输出的内容
传送了操作系统，操作系统会根据系统的编码对输入的字节流进行编码，这就解释了为什么utf-8格式的字符串&#8220;哈哈&#8221;，输出的是&#8220;鍝堝搱&#8221;，因为
'\xe5\x93\x88\xe5\x93\x88'用GB2312去解释，其显示的出来就是&#8220;鍝堝搱&#8221;。这里再强调一下，str记录的是字节数组，只
是某种编码的存储格式，至于输出到文件或是打印出来是什么格式，完全取决于其解码的编码将它解码成什么样子。</span></span></p>
<p class="p0"><span><span style="font-family: 宋体;">这里再对print进行一点补充说明：当将一个unicode对象传给print时，在内部会将该unicode对象进行一次转换，转换成本地的默认编码（这仅是个人猜测）</span></span></p>
<h4><span>二、str<span style="font-family: 宋体;">和unicode对象的转换</span></span></h4>
<p class="p0"><span>str<span style="font-family: 宋体;">和unicode对象的转换，通过encode和decode实现，具体使用如下：</span></span></p>
<p class="p0"><span><span style="font-family: 宋体;"><img src="http://p.blog.csdn.net/images/p_blog_csdn_net/kiki113/EntryImages/20090409/encode_decode.jpg" alt="decode和encode演示" height="57" width="338" /></span></span></p>
<p class="p0"><span><span style="font-family: 宋体;">将GBK'哈哈'转换成unicode，然后再转换成UTF8</span></span></p>
<h4><span><span style="font-family: 宋体;">三、Setdefaultencoding</span></span></h4>
<p class="p0"><span><span style="font-family: 宋体;"><img src="http://p.blog.csdn.net/images/p_blog_csdn_net/kiki113/EntryImages/20090409/setdefaultencoding.jpg" alt="setdefaultencoding" height="240" width="640" /></span></span></p>
<p class="p0"><span><span style="font-family: 宋体;">如上图的演示代码所示：</span></span></p>
<p class="p0"><span><span style="font-family: 宋体;">当把s(gbk字符串)直接编码成utf-8的时候，将抛出异常，但是通过调用如下代码：</span></span></p>
<p class="p0" style="text-align: left;"><span>import&nbsp;sys</span></p>
<p class="p0" style="text-align: left;"><span>reload(sys)</span></p>
<p class="p0" style="text-align: left;"><span>sys.setdefaultencoding('gbk')</span></p>
<p class="p0"><span><span style="font-family: 宋体;">后就可以转换成功，为什么呢？<span style="font-family: Verdana;"><span><span style="font-family: 宋体;">在python中str和unicode在编码和解码过程中，如果将一个str直接编码成另一种编码，会先把str解码成unicode，采用的编码为默认编码，一般默认编码是</span></span><span>ansci</span><span>i<span style="font-family: 宋体;">，所以在上面示例代码中第一次转换的时候会出错，当设定当前默认编码为'gbk'后，就不会出错了。</span></span></span></span></span></p>
<p class="p0"><span><span style="font-family: 宋体;">至于reload(sys)是因为</span></span><span>Python2.5&nbsp;<span style="font-family: 宋体;">初始化后会删除&nbsp;sys.setdefaultencoding&nbsp;这个方法，我们需要重新载入</span></span><span><span style="font-family: 宋体;">。</span></span></p>
<h4><span><span style="font-family: 宋体;">四、操作不同文件的编码格式的文件</span></span></h4>
<p>建立一个文件test.txt，文件格式用ANSI，内容为:</p>
<p>abc中文</p>
<p>用python来读取</p>
<p># coding=gbk</p>
<p>print open("Test.txt").read()</p>
<p>结果：abc中文</p>
<p>把文件格式改成UTF-8：</p>
<p>结果：abc涓枃</p>
<p>显然，这里需要解码：</p>
<p># coding=gbk</p>
<p>import codecs</p>
<p>print open("Test.txt").read().decode("utf-8")</p>
<p>结果：abc中文</p>
<p>上面的test.txt我是用Editplus来编辑的，但当我用Windows自带的记事本编辑并存成UTF-8格式时，</p>
<p>运行时报错：</p>
<p>Traceback (most recent call last):</p>
<p>File "ChineseTest.py", line 3, in&nbsp;</p>
<p>print open("Test.txt").read().decode("utf-8")</p>
<p>UnicodeEncodeError: 'gbk' codec can't encode character u'\ufeff' in position 0: illegal multibyte sequence</p>
<p>原来，某些软件，如notepad，在保存一个以UTF-8编码的文件时，会在文件开始的地方插入三个不可见的字符（0xEF 0xBB 0xBF，即BOM）。</p>
<p>因此我们在读取时需要自己去掉这些字符，python中的codecs module定义了这个常量：</p>
<p># coding=gbk</p>
<p>import codecs</p>
<p>data = open("Test.txt").read()</p>
<p>if data[:3] == codecs.BOM_UTF8:</p>
<p>data = data[3:]</p>
<p>print data.decode("utf-8")</p>
<p>结果：abc中文</p>
<p><strong>五、文件的编码格式和编码声明的作用</strong></p>
<p class="p0"><span><span style="font-family: 宋体;">源文件的编码格式对字符串的声明有什么作用呢？这个问题困扰一直困扰了我好久，现在终于有点眉目了，文件的编码格式决定了在该源文件中声明的字符串的编码格式，例如：</span></span></p>
<p class="p0"><span>str&nbsp;=&nbsp;'<span style="font-family: 宋体;">哈哈'</span></span></p>
<p class="p0"><span>print&nbsp;repr(str)</span></p>
<p class="p0"><span>a.<span style="font-family: 宋体;">如果文件格式为utf-8，则str的值为：'\xe5\x93\x88\xe5\x93\x88'（哈哈的utf-8编码）</span></span></p>
<p class="p0"><span>b.<span style="font-family: 宋体;">如果文件格式为gbk，则str的值为：'\xb9\xfe\xb9\xfe'（哈哈的gbk编码）</span></span></p>
<p class="p0"><span><span style="font-family: 宋体;">在第一节已经说过，python中的字符串，
只是一个字节数组，所以当把a情况的str输出到gbk编码的控制台时，就将显示为乱码：鍝堝搱；而当把b情况下的str输出utf-8编码的控制台时，
也将显示乱码的问题，是什么也没有，也许'\xb9\xfe\xb9\xfe'用utf-8解码显示，就是空白吧。&gt;_&lt;</span></span></p>
<p class="p0"><span><span style="font-family: 宋体;">说完文件格式，现在来谈谈编码</span></span><span><span style="font-family: 宋体;">声明</span></span><span><span style="font-family: 宋体;">的作用吧，每个文件在最上面的地方，都会用#&nbsp;coding=gbk&nbsp;类似的语句声明一下编码，但是这个声明到底有什么用呢？到止前为止，我觉得它的作用也就是三个：</span></span></p>
<p><span style="font-family: 宋体;">
<ol>
    <li>声明源文件中将出现非ascii编码，通常也就是中文；</li>
    <li>在高级的IDE中，IDE会将你的文件格式保存成你指定编码格式。</li>
    <li>决定源码中类似于u'哈'这类声明的将&#8216;哈&#8217;解码成unicode所用的编码格式，也是一个比较容易让人迷惑的地方，看示例：</li>
</ol>
<span style="font-family: Verdana;">#coding:gbk</span><br />
</span></p>
<p class="p0"><span>ss&nbsp;=&nbsp;u'<span style="font-family: 宋体;">哈哈'</span></span></p>
<p class="p0"><span>print&nbsp;repr(ss)</span></p>
<p class="p0"><span>print&nbsp;'ss:%s'&nbsp;%&nbsp;ss</span></p>
<p class="p0"><span><span style="font-family: 宋体;">将这个些代码保存成一个utf-8文本，运行，你认为会输出什么呢？大家第一感觉肯定输出的肯定是：</span></span></p>
<p class="p0"><span>u'\u54c8\u54c8'</span></p>
<p class="p0"><span>ss:<span style="font-family: 宋体;">哈哈</span></span></p>
<p class="p0"><span><span style="font-family: 宋体;">但是实际上输出是：</span></span></p>
<p class="p0"><span>u'\u935d\u581d\u6431'</span></p>
<p class="p0"><span>ss:<span style="font-family: 宋体;">鍝堝搱</span></span></p>
<p class="p0"><span><span style="font-family: 宋体;">为什么会这样，这时候，就是编码声明在作怪了，在运行ss&nbsp;=&nbsp;u'哈哈'的时候，整个过程可以分为以下几步：</span></span></p>
<p class="p0"><span>1)&nbsp;</span><span><span style="font-family: 宋体;">获取'哈哈'的编码：由文件编码格式确定，为'\xe5\x93\x88\xe5\x93\x88'（哈哈的utf-8编码形式）</span></span></p>
<p class="p0"><span>2)&nbsp;</span><span><span style="font-family: 宋体;">转成
unicode编码的时候，在这个转换的过程中，对于'\xe5\x93\x88\xe5\x93\x88'的解码，不是用utf-8解码，而是用声明编
码处指定的编码GBK，将'\xe5\x93\x88\xe5\x93\x88'按GBK解码，得到就是''鍝堝搱''，这三个字的unicode编码就
是u'\u935d\u581d\u6431'，至止可以解释为什么print&nbsp;repr(ss)输出的是u'\u935d\u581d\u6431'
了。</span></span></p>
<p class="p0"><span><span style="font-family: 宋体;">好了，这里有点绕，我们来分析下一个示例：</span></span></p>
<p class="p0"><span>#-*-&nbsp;coding:utf-8&nbsp;-*-</span></p>
<p class="p0"><span>ss&nbsp;=&nbsp;u'<span style="font-family: 宋体;">哈哈'</span></span></p>
<p class="p0"><span>print&nbsp;repr(ss)</span></p>
<p class="p0"><span>print&nbsp;'ss:%s'&nbsp;%&nbsp;ss</span></p>
<p class="p0"><span><span style="font-family: 宋体;">将这个示例这次保存成GBK编码形式，运行结果，竟然是：</span></span></p>
<p class="p0"><span>UnicodeDecodeError:&nbsp;'utf8'&nbsp;codec&nbsp;can't&nbsp;decode&nbsp;byte&nbsp;0xb9&nbsp;in&nbsp;position&nbsp;0:&nbsp;unexpected&nbsp;code&nbsp;byte</span></p>
<p class="p0"><span><span style="font-family: 宋体;">这里为什么会有utf8解码错误呢？想想上个
示例也明白了，转换第一步，因为文件编码是GBK，得到的是'哈哈'编码是GBK的编码'\xb9\xfe\xb9\xfe'，当进行第二步，转换成
unicode的时候，会用UTF8对'\xb9\xfe\xb9\xfe'进行解码，而大家查utf-8的编码表会发现，utf8编码表（关于UTF-
8解释可参见<a class="example1" href="http://blog.csdn.net/kiki113/archive/2009/04/10/4061988.aspx" target="_blank">字符编码笔记：ASCII、UTF-8、UNICODE</a>）中根本不存在，所以会报上述错误。</span></span></p>
<img src ="http://www.blogjava.net/pts/aggbug/284124.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/pts/" target="_blank">pts</a> 2009-06-25 15:59 <a href="http://www.blogjava.net/pts/archive/2009/06/25/284124.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]字符编码笔记：ASCII，Unicode和UTF-8</title><link>http://www.blogjava.net/pts/archive/2009/06/25/284121.html</link><dc:creator>pts</dc:creator><author>pts</author><pubDate>Thu, 25 Jun 2009 07:57:00 GMT</pubDate><guid>http://www.blogjava.net/pts/archive/2009/06/25/284121.html</guid><wfw:comment>http://www.blogjava.net/pts/comments/284121.html</wfw:comment><comments>http://www.blogjava.net/pts/archive/2009/06/25/284121.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/pts/comments/commentRss/284121.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/pts/services/trackbacks/284121.html</trackback:ping><description><![CDATA[<a href="http://blog.csdn.net/kiki113/archive/2009/04/10/4061988.aspx">From:</a>很值得每个programmer看看<br />
<br />
<p><span style="text-decoration: underline;">字符编码是计算机技术的基石，想要熟练使用计算机，就必须懂得一点字符编码的知识</span>。</p>
<h4>1. ASCII码</h4>
<p>我们知道，在计算机内部，所有的信息最终都表示为一个二进制的字符串。每一个二进制位（bit）有0和1两种状态，因此八个二进制位就可以组合出
256种状态，这被称为一个字节（byte）。也就是说，一个字节一共可以用来表示256种不同的状态，每一个状态对应一个符号，就是256个符号，从
0000000到11111111。</p>
<p>上个世纪60年代，美国制定了一套字符编码，对英语字符与二进制位之间的关系，做了统一规定。这被称为ASCII码，一直沿用至今。</p>
<p>ASCII码一共规定了128个字符的编码，比如空格&#8220;SPACE&#8221;是32（二进制00100000），大写的字母A是65（二进制01000001）。这128个符号（包括32个不能打印出来的控制符号），只占用了一个字节的后面7位，最前面的1位统一规定为0。</p>
<h4>2、非ASCII编码</h4>
<p>英语用128个符号编码就够了，但是用来表示其他语言，128个符号是不够的。比如，在法语中，字母上方有注音符号，它就无法用ASCII码表示。
于是，一些欧洲国家就决定，利用字节中闲置的最高位编入新的符号。比如，法语中的&#233;的编码为130（二进制10000010）。这样一来，这些欧洲国家使
用的编码体系，可以表示最多256个符号。</p>
<p>但是，这里又出现了新的问题。不同的国家有不同的字母，因此，哪怕它们都使用256个符号的编码方式，代表的字母却不一样。比如，130在法语编码
中代表了&#233;，在希伯来语编码中却代表了字母Gimel
(ג)，在俄语编码中又会代表另一个符号。但是不管怎样，所有这些编码方式中，0—127表示的符号是一样的，不一样的只是128—255的这一段。</p>
<p>至于亚洲国家的文字，使用的符号就更多了，汉字就多达10万左右。一个字节只能表示256种符号，肯定是不够的，就必须使用多个字节表达一个符号。
比如，简体中文常见的编码方式是GB2312，使用两个字节表示一个汉字，所以理论上最多可以表示256x256=65536个符号。</p>
<p>中文编码的问题需要专文讨论，这篇笔记不涉及。这里只指出，虽然都是用多个字节表示一个符号，但是GB类的汉字编码与后文的Unicode和UTF-8是毫无关系的。</p>
<h4>3.Unicode</h4>
<p>正如上一节所说，世界上存在着多种编码方式，同一个二进制数字可以被解释成不同的符号。因此，要想打开一个文本文件，就必须知道它的编码方式，否则用错误的编码方式解读，就会出现乱码。为什么电子邮件常常出现乱码？就是因为发信人和收信人使用的编码方式不一样。</p>
<p>可以想象，如果有一种编码，将世界上所有的符号都纳入其中。每一个符号都给予一个独一无二的编码，那么乱码问题就会消失。这就是Unicode，就像它的名字都表示的，这是一种所有符号的编码。</p>
<p>Unicode当然是一个很大的集合，现在的规模可以容纳100多万个符号。每个符号的编码都不一样，比如，U+0639表示阿拉伯字母
Ain，U+0041表示英语的大写字母A，U+4E25表示汉字&#8220;严&#8221;。具体的符号对应表，可以查询unicode.org，或者专门的汉字对应表。</p>
<h4>4. Unicode的问题</h4>
<p>需要注意的是，Unicode只是一个符号集，它只规定了符号的二进制代码，却没有规定这个二进制代码应该如何存储。</p>
<p>比如，汉字&#8220;严&#8221;的unicode是十六进制数4E25，转换成二进制数足足有15位（100111000100101），也就是说这个符号的表示至少需要2个字节。表示其他更大的符号，可能需要3个字节或者4个字节，甚至更多。</p>
<p>这里就有两个严重的问题，第一个问题是，如何才能区别unicode和ascii？计算机怎么知道三个字节表示一个符号，而不是分别表示三个符号
呢？第二个问题是，我们已经知道，英文字母只用一个字节表示就够了，如果unicode统一规定，每个符号用三个或四个字节表示，那么每个英文字母前都必
然有二到三个字节是0，这对于存储来说是极大的浪费，文本文件的大小会因此大出二三倍，这是无法接受的。</p>
<p>它们造成的结果是：1）出现了unicode的多种存储方式，也就是说有许多种不同的二进制格式，可以用来表示unicode。2）unicode在很长一段时间内无法推广，直到互联网的出现。</p>
<h4>5.UTF-8</h4>
<p>互联网的普及，强烈要求出现一种统一的编码方式。UTF-8就是在互联网上使用最广的一种unicode的实现方式。其他实现方式还包括UTF-16和UTF-32，不过在互联网上基本不用。重复一遍，这里的关系是，UTF-8是Unicode的实现方式之一。</p>
<p>UTF-8最大的一个特点，就是它是一种变长的编码方式。它可以使用1~4个字节表示一个符号，根据不同的符号而变化字节长度。</p>
<p>UTF-8的编码规则很简单，只有二条：</p>
<p>1）对于单字节的符号，字节的第一位设为0，后面7位为这个符号的unicode码。因此对于英语字母，UTF-8编码和ASCII码是相同的。</p>
<p>2）对于n字节的符号（n&gt;1），第一个字节的前n位都设为1，第n+1位设为0，后面字节的前两位一律设为10。剩下的没有提及的二进制位，全部为这个符号的unicode码。</p>
<p>下表总结了编码规则，字母x表示可用编码的位。</p>
<p><img src="http://p.blog.csdn.net/images/p_blog_csdn_net/kiki113/EntryImages/20090410/utf8.jpg" alt="UTF-8范围" height="252" width="589" /></p>
<p>下面，还是以汉字&#8220;严&#8221;为例，演示如何实现UTF-8编码。</p>
<p>已知&#8220;严&#8221;的unicode是4E25（100111000100101），根据上表，可以发现4E25处在第三行的范围内（0000
0800-0000 FFFF），因此&#8220;严&#8221;的UTF-8编码需要三个字节，即格式是&#8220;1110xxxx 10xxxxxx
10xxxxxx&#8221;。然后，从&#8220;严&#8221;的最后一个二进制位开始，依次从后向前填入格式中的x，多出的位补0。这样就得到了，&#8220;严&#8221;的UTF-8编码是
&#8220;11100100 10111000 10100101&#8221;，转换成十六进制就是E4B8A5。</p>
<h4>6. Unicode与UTF-8之间的转换</h4>
<p>通过上一节的例子，可以看到&#8220;严&#8221;的Unicode码是4E25，UTF-8编码是E4B8A5，两者是不一样的。它们之间的转换可以通过程序实现。</p>
<p>在Windows平台下，有一个最简单的转化方法，就是使用内置的记事本小程序Notepad.exe。打开文件后，点击&#8220;文件&#8221;菜单中的&#8220;另存为&#8221;命令，会跳出一个对话框，在最底部有一个&#8220;编码&#8221;的下拉条。</p>
<p><img src="http://p.blog.csdn.net/images/p_blog_csdn_net/kiki113/EntryImages/20090410/SaveAs.jpg" alt="SaveAs" height="227" width="500" /></p>
<p>里面有四个选项：ANSI，Unicode，Unicode big endian 和 UTF-8。</p>
<p>1）ANSI是默认的编码方式。对于英文文件是ASCII编码，对于简体中文文件是GB2312编码（只针对Windows简体中文版，如果是繁体中文版会采用Big5码）。</p>
<p>2）Unicode编码指的是UCS-2编码方式，即直接用两个字节存入字符的Unicode码。这个选项用的little endian格式。</p>
<p>3）Unicode big endian编码与上一个选项相对应。我在下一节会解释little endian和big endian的涵义。</p>
<p>4）UTF-8编码，也就是上一节谈到的编码方法。</p>
<p>选择完&#8221;编码方式&#8220;后，点击&#8221;保存&#8220;按钮，文件的编码方式就立刻转换好了。</p>
<h4>7. Little endian和Big endian</h4>
<p>上一节已经提到，Unicode码可以采用UCS-2格式直接存储。以汉字&#8221;严&#8220;为例，Unicode码是4E25，需要用两个字节存储，一个字节
是4E，另一个字节是25。存储的时候，4E在前，25在后，就是Big endian方式；25在前，4E在后，就是Little endian方式。</p>
<p>这两个古怪的名称来自英国作家斯威夫特的《格列佛游记》。在该书中，小人国里爆发了内战，战争起因是人们争论，吃鸡蛋时究竟是从大头(Big-
Endian)敲开还是从小头(Little-Endian)敲开。为了这件事情，前后爆发了六次战争，一个皇帝送了命，另一个皇帝丢了王位。</p>
<p>因此，第一个字节在前，就是&#8221;大头方式&#8220;（Big endian），第二个字节在前就是&#8221;小头方式&#8220;（Little endian）。</p>
<p>那么很自然的，就会出现一个问题：计算机怎么知道某一个文件到底采用哪一种方式编码？</p>
<p>Unicode规范中定义，每一个文件的最前面分别加入一个表示编码顺序的字符，这个字符的名字叫做&#8221;零宽度非换行空格&#8220;（ZERO WIDTH NO-BREAK SPACE），用FEFF表示。这正好是两个字节，而且FF比FE大1。</p>
<p>如果一个文本文件的头两个字节是FE FF，就表示该文件采用大头方式；如果头两个字节是FF FE，就表示该文件采用小头方式。</p>
<h4>8. 实例</h4>
<p>下面，举一个实例。</p>
<p>打开&#8221;记事本&#8220;程序Notepad.exe，新建一个文本文件，内容就是一个&#8221;严&#8220;字，依次采用ANSI，Unicode，Unicode big endian 和 UTF-8编码方式保存。</p>
<p>然后，用文本编辑软件UltraEdit中的&#8221;十六进制功能&#8220;，观察该文件的内部编码方式。</p>
<p>1）ANSI：文件的编码就是两个字节&#8220;D1 CF&#8221;，这正是&#8220;严&#8221;的GB2312编码，这也暗示GB2312是采用大头方式存储的。</p>
<p>2）Unicode：编码是四个字节&#8220;FF FE 25 4E&#8221;，其中&#8220;FF FE&#8221;表明是小头方式存储，真正的编码是4E25。</p>
<p>3）Unicode big endian：编码是四个字节&#8220;FE FF 4E 25&#8221;，其中&#8220;FE FF&#8221;表明是大头方式存储。</p>
<p>4）UTF-8：编码是六个字节&#8220;EF BB BF E4 B8 A5&#8221;，前三个字节&#8220;EF BB BF&#8221;表示这是UTF-8编码，后三个&#8220;E4B8A5&#8221;就是&#8220;严&#8221;的具体编码，它的存储顺序与编码顺序是一致的。</p>
<img src ="http://www.blogjava.net/pts/aggbug/284121.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/pts/" target="_blank">pts</a> 2009-06-25 15:57 <a href="http://www.blogjava.net/pts/archive/2009/06/25/284121.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>将chartdirector创建的image嵌入网页的两种方法</title><link>http://www.blogjava.net/pts/archive/2009/06/15/282335.html</link><dc:creator>pts</dc:creator><author>pts</author><pubDate>Mon, 15 Jun 2009 06:03:00 GMT</pubDate><guid>http://www.blogjava.net/pts/archive/2009/06/15/282335.html</guid><wfw:comment>http://www.blogjava.net/pts/comments/282335.html</wfw:comment><comments>http://www.blogjava.net/pts/archive/2009/06/15/282335.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/pts/comments/commentRss/282335.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/pts/services/trackbacks/282335.html</trackback:ping><description><![CDATA[这里详细说明了在网页中嵌入chartdirector元素的两种方法<br />
<br />
<table bgcolor="#ccccee" border="0" cellpadding="6" cellspacing="1" width="770">
    <tbody>
        <tr>
            <th colspan="2" align="left" valign="middle">Django integration</th>
        </tr>
        <tr>
            <td bgcolor="#edeff3" valign="middle" width="60%">Posted by GMalla on Mar-02-2008 23:28</td>
            <td align="right" bgcolor="#c0cad6" width="40%">
            <div class="menu">| <a href="http://www.chartdir.com/forum/post.php?bn=chartdir_support&amp;key=1204518493&amp;site=chartdir" onmouseover="window.status='Reply to this message';return true" onmouseout="window.status='';return true" class="link"><acronym title="Reply to this message">Reply</acronym></a> | <a href="http://www.chartdir.com/forum/subscribe_thread.php?site=chartdir&amp;bn=chartdir_support&amp;thread=1204518493" onmouseover="window.status='Receive updates to this thread';return true" onmouseout="window.status='';return true" class="link"><acronym title="Receive updates to this thread">Monitor</acronym></a></div>
            </td>
        </tr>
        <tr bgcolor="#ffffff" valign="middle">
            <td colspan="2" align="left"><span class="message">Hi,<br />
            &nbsp;&nbsp;I'm using Django framework for my <span style="background: #ffff99 none repeat scroll 0% 0%; color: #000000; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><strong>web</strong></span>
            application. How do i integrate chart director with Django custom
            views. In Django views define context and the context is passed to a
            html template. Html template creates output html file. My question is
            how to I pass a parameter to &lt;IMG SRC="/home/simplebar.py"&gt; .
            Because in Django the URLs do not end with .py extension. This again
            need to be mapped to a view function. I'm bit confuse.<br />
            Please help.<br />
            <br />
            Thanks<br />
            GMalla</span></td>
        </tr>
    </tbody>
</table>
<br />
<a style="width: 20px; height: 20px; text-indent: 20px; background-repeat: no-repeat; background-image: url(/CuteSoft_Client/CuteEditor/Load.ashx?type=image&amp;file=anchor.gif);" name="N1204518493END"></a> <a style="width: 20px; height: 20px; text-indent: 20px; background-repeat: no-repeat; background-image: url(/CuteSoft_Client/CuteEditor/Load.ashx?type=image&amp;file=anchor.gif);" name="N1204569116"></a>  <!-- TEMPLATE -->
<table bgcolor="#ccccee" border="0" cellpadding="6" cellspacing="1" width="770">
    <tbody>
        <tr>
            <th colspan="2" align="left" valign="middle"><img src="http://www.chartdir.com/forum/images/thread.gif" align="absmiddle"  alt="" />&nbsp; Re: Django integration</th>
        </tr>
        <tr>
            <td bgcolor="#edeff3" valign="middle" width="60%">Posted by Peter Kwan on Mar-03-2008 13:31</td>
            <td align="right" bgcolor="#c0cad6" width="40%">
            <div class="menu">| <a href="http://www.chartdir.com/forum/post.php?bn=chartdir_support&amp;key=1204569116&amp;site=chartdir" onmouseover="window.status='Reply to this message';return true" onmouseout="window.status='';return true" class="link"><acronym title="Reply to this message">Reply</acronym></a> | <a href="http://www.chartdir.com/forum/subscribe_thread.php?site=chartdir&amp;bn=chartdir_support&amp;thread=1204518493" onmouseover="window.status='Receive updates to this thread';return true" onmouseout="window.status='';return true" class="link"><acronym title="Receive updates to this thread">Monitor</acronym></a></div>
            </td>
        </tr>
        <tr bgcolor="#ffffff" valign="middle">
            <td colspan="2" align="left"><span class="message">Hi GMalla,<br />
            <br />
            I have never used Django before. However, I have seen many frameworks, so I may provide some general ideas.<br />
            <br />
            There are two methods to output a chart in a <span style="background: #ffff99 none repeat scroll 0% 0%; color: #000000; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><strong>web</strong></span> page.<br />
            <br />
            (1) Create the chart as an image file, then output the image file. For example, if you are using the sample code in "<span style="background: #ffff99 none repeat scroll 0% 0%; color: #000000; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><strong>python</strong></span>demo/simplebar.py"
            (*not* the CGI one), it is creating the chart as a file
            "simplebar.png". So after crreating the chart, in your &lt;IMG&gt; tag,
            you may use &lt;IMG SRC="/path/to/simplebar.png"&gt;.<br />
            <br />
            If you use this method, the followings are several important things to note:<br />
            <br />
            - To avoid confusion, you should use the full path name, not a relative path name. Some <span style="background: #ffff99 none repeat scroll 0% 0%; color: #000000; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><strong>web</strong></span>
            frameworks will use some strange directory as the "current working
            directory", and your relative path name may end up relative to some
            strange place.<br />
            <br />
            - Please be aware the path in the "makeChart"
            call is a file system path name, not a URL path. For example,
            "/aaa,png" means storing "aaa.png" in the root of the hard disk, not
            the root of your <span style="background: #ffff99 none repeat scroll 0% 0%; color: #000000; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><strong>web</strong></span> directory. (Of course, the &lt;IMG&gt; tag path is a URL, as per HTML standard.)<br />
            <br />
            - Make sure your <span style="background: #ffff99 none repeat scroll 0% 0%; color: #000000; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><strong>web</strong></span> server has read and write access to the directory. By default, the <span style="background: #ffff99 none repeat scroll 0% 0%; color: #000000; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><strong>web</strong></span>
            server, usually running as the anonymous user, may not write to the
            hard disk. For testing, you may want to set the directory to be
            readable and writable to anyone.<br />
            <br />
            - The sample code uses a hard coded file name "simplebar.png". For a <span style="background: #ffff99 none repeat scroll 0% 0%; color: #000000; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><strong>web</strong></span>
            server, you may want to use a unique file name, otherwise two users
            accessing the server at the same time will overwrite each other's
            files. The BaseChart.makeTmpFile method in ChartDirector may be useful
            for this purpose.<br />
            <br />
            <br />
            (2) Another method is to create the chart as an image in memory, then stream the image to the browser. Most well-developed <span style="background: #ffff99 none repeat scroll 0% 0%; color: #000000; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><strong>web</strong></span> framework supports streaming of non-HTML content, such as images, movies, etc.. In the "<span style="background: #ffff99 none repeat scroll 0% 0%; color: #000000; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><strong>python</strong></span>demo_cgi/simplebar.py" sample code, the following method is used to stream the content to the browser:<br />
            <br />
            print "Content-type: image/png\n"<br />
            binaryPrint(c.makeChart2(PNG))<br />
            <br />
            For
            your Django framework, you may need to read the Django documentation,
            or post questions to Django support or Django forum to ask if Django
            can stream non-HTML content. If it can, then you may replace the above
            two lines with the Django streaming code. In this case, the &lt;IMG&gt;
            tag is &lt;IMG SRC="/path/to/yourDjangoCode.xxx"&gt; where
            yourDjangoCode.xxx is the Django code that creates the chart and
            streams it to the browser.<br />
            <br />
            If Django does not support non-HTML content, then you must use method (1) above.<br />
            <br />
            <br />
            Hope this can help.<br />
            <br />
            Regards<br />
            Peter Kwan</span></td>
        </tr>
    </tbody>
</table>
<br />
<a style="width: 20px; height: 20px; text-indent: 20px; background-repeat: no-repeat; background-image: url(/CuteSoft_Client/CuteEditor/Load.ashx?type=image&amp;file=anchor.gif);" name="N1204569116END"></a> <a style="width: 20px; height: 20px; text-indent: 20px; background-repeat: no-repeat; background-image: url(/CuteSoft_Client/CuteEditor/Load.ashx?type=image&amp;file=anchor.gif);" name="N1206365292"></a>  <!-- TEMPLATE -->
<table bgcolor="#ccccee" border="0" cellpadding="6" cellspacing="1" width="770">
    <tbody>
        <tr>
            <th colspan="2" align="left" valign="middle"><img src="http://www.chartdir.com/forum/images/thread.gif" align="absmiddle"  alt="" />&nbsp; Re: Django integration</th>
        </tr>
        <tr>
            <td bgcolor="#edeff3" valign="middle" width="60%">Posted by Adrian on Mar-24-2008 09:28</td>
            <td align="right" bgcolor="#c0cad6" width="40%">
            <div class="menu">| <a href="http://www.chartdir.com/forum/post.php?bn=chartdir_support&amp;key=1206365292&amp;site=chartdir" onmouseover="window.status='Reply to this message';return true" onmouseout="window.status='';return true" class="link"><acronym title="Reply to this message">Reply</acronym></a> | <a href="http://www.chartdir.com/forum/subscribe_thread.php?site=chartdir&amp;bn=chartdir_support&amp;thread=1204518493" onmouseover="window.status='Receive updates to this thread';return true" onmouseout="window.status='';return true" class="link"><acronym title="Receive updates to this thread">Monitor</acronym></a></div>
            </td>
        </tr>
        <tr bgcolor="#ffffff" valign="middle">
            <td colspan="2" align="left"><span class="message">A quick Django integration:<br />
            <br />
            1) Add your URL pattern:<br />
            url(r'^test.png$', views.test, name='url_chart_test'),<br />
            <br />
            2) create your view function:<br />
            <br />
            from django.http import *<br />
            from pychartdir import *<br />
            <br />
            def test(request):<br />
            &nbsp;&nbsp;&nbsp;&nbsp;data = [85, 156, 179.5, 211, 123]<br />
            &nbsp;&nbsp;&nbsp;&nbsp;labels = ["Mon", "Tue", "Wed", "Thu", "Fri"]<br />
            &nbsp;&nbsp;&nbsp;&nbsp;c = XYChart(250, 250)<br />
            &nbsp;&nbsp;&nbsp;&nbsp;c.setPlotArea(30, 20, 200, 200)<br />
            &nbsp;&nbsp;&nbsp;&nbsp;c.addBarLayer(data)<br />
            &nbsp;&nbsp;&nbsp;&nbsp;c.addBarLayer(data)<br />
            <br />
            &nbsp;&nbsp;&nbsp;&nbsp;response = HttpResponse( mimetype='image/png')<br />
            &nbsp;&nbsp;&nbsp;&nbsp;response.write(c.makeChart2(PNG))<br />
            <br />
            &nbsp;&nbsp;&nbsp;&nbsp;return response<br />
            <br />
            3) in your html page, add a link to this "image"<br />
            &lt;img src="/whatever/test.png"&gt;</span></td>
        </tr>
    </tbody>
</table>
<br />
<br />
<img src ="http://www.blogjava.net/pts/aggbug/282335.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/pts/" target="_blank">pts</a> 2009-06-15 14:03 <a href="http://www.blogjava.net/pts/archive/2009/06/15/282335.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]编程中的命名设计那点事</title><link>http://www.blogjava.net/pts/archive/2009/06/13/282089.html</link><dc:creator>pts</dc:creator><author>pts</author><pubDate>Sat, 13 Jun 2009 14:50:00 GMT</pubDate><guid>http://www.blogjava.net/pts/archive/2009/06/13/282089.html</guid><wfw:comment>http://www.blogjava.net/pts/comments/282089.html</wfw:comment><comments>http://www.blogjava.net/pts/archive/2009/06/13/282089.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/pts/comments/commentRss/282089.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/pts/services/trackbacks/282089.html</trackback:ping><description><![CDATA[<p><a target="_blank" href="http://cocre.com/?p=990">From:</a> 好的命名确是很重要，也是显示设计思路是否清晰的重要指标<br /></p><p>在我开始设计系统的时候，我会花去很多时间去设计命名，因为好的命名和好的设计是分不开的。</p> <blockquote><p>In the beginning was the <strong>Word</strong>, and the Word was with God, and the Word was God<br />太初有道。道与神同在，道就是神。 (约翰福音第一章，第一节)</p></blockquote> <p><font color="#ff0000"><big><big>在设计过程中给类，方法和函数好的命名会带来好的设计，虽然这不是一定成立，但是如果坏的命名那一定不会给你带来好的设计。在设计过程，如果你发现 你很难命名某一个模块，某个方法时，可能你真正遇到的问题不是难命名的问题，而是这个设计是否真的合理，你或许应该花更多的时间来重新设计一下你的模块。<font color="#000000"><small>【无语，我就经常犯，功力不够呀】</small></font></big></big></font></p> <p>好的命名不仅会带来好的设计，好的命名还提高了程序的可读性，降低代码维护的成本。另一方面，如果糟糕的命名会给代码带来一堵无形的墙，让你必须深入代码去研究代码具有的行为，增加你理解代码的时间。</p> <p>为此我总结了几条关于命名的指导原则，希望这几条原则能为你的命名设计带来帮助，我使用的是C++的语法，当然这些原则也很容易扩展到其他语言中去。</p> <h3><span style="color: rgb(51, 153, 102);">类型命名(类，接口，和结构)</span></h3> <p><span style="color: rgb(51, 153, 102);"><br /></span></p> <p><span style="color: rgb(0, 0, 255);"><strong>名字应该尽量采用名词</strong></span><br /><code>Bad:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Happy<br />Good:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Happiness</code></p> <p><span id="more-990"></span></p> <p><span style="color: rgb(0, 0, 255);"><strong>不要使用类似名字空间的前缀</strong></span><br /><code>Bad:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SystemOnlineMessage<br />Good:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System::Online:Message<br /></code></p> <p><span style="color: rgb(0, 0, 255);"><strong>形容词不要用太多，能描述清楚就行</strong></span><br /><code>Bad:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IAbstractFactoryPatternBase<br />Good:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IFactory<br /></code></p> <p><span style="color: rgb(0, 0, 255);"><strong>在类型中不要使用Manager 或则 Helper 或则其他没意义的单词</strong></span><br />如果你一定要在一个类型上加上Manager或Helper，那么这个类型要么就是命名的非常糟糕，要么就是设计的非常糟糕，如果是后则，那么这个类型就应该管理manage和帮助help一下自己了。<br /><code>Bad:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ConnectionManager<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;XmlHelper<br />Good:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Connection<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;XmlDocument, XmlNode, etc.<br /></code></p> <p><span style="color: rgb(0, 0, 255);"><strong>如果某个类不能通过简单的命名来描述它具有的功能，可以考虑用类比的方式来命名</strong></span><code><br />Bad:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IncomingMessageQueue<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CharacterArray<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SpatialOrganizer<br />Good:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Mailbox<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;String<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Map<br /></code></p> <p><span style="color: rgb(0, 0, 255);"><strong>如果你使用类比，你就应该一致的使用它们</strong></span><br /><code>Bad:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Mailbox,DestinationID<br />Good:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Mailbox,Address<br /></code></p> <h3><span style="color: rgb(51, 153, 102);">函数(方法和过程)</span></h3> <p><span style="color: rgb(51, 153, 102);"><br /></span></p> <p><span style="color: rgb(0, 0, 255);"><strong>简洁</strong></span><br /><code>Bad:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list.GetNumberOfItems()<br />Good:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list.Count()<br /></code></p> <p><span style="color: rgb(0, 0, 255);"><strong>不要太简洁</strong></span><br /><code>Bad:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list.Verify()<br />Good:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list.ContainsNull()<br /></code></p> <p><span style="color: rgb(0, 0, 255);"><strong>避免缩写</strong></span><br /><code>Bad:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list.Srt()<br />Good:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list.Sort()<br /></code></p> <p><span style="color: rgb(0, 0, 255);"><strong>对于完成某件事情的函数使用动词</strong></span><br /><code>Bad:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;obj.RefCount();<br />Good:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list.Clear();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list.Sort();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;obj.AddReference();<br /></code></p> <p><span style="color: rgb(0, 0, 255);"><strong>对于返回布尔型的函数，使用类似提问的方式</strong></span><br /><code>Bad:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list.Empty();<br />Good:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list.IsEmpty();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list.Contains(item);<br /></code></p> <p><span style="color: rgb(0, 0, 255);"><strong>对于只是返回属性，而不改变状态的函数则使用名词</strong></span><br /><code>Bad:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list.GetCount();<br />Good:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list.Count();<br /></code></p> <p><span style="color: rgb(0, 0, 255);"><strong>不要在函数名字中重复参数的名称</strong></span><br /><code>Bad:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list.AddItem(item);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;handler.ReceiveMessage(msg);<br />Good:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list.Add(item);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;handler.Receive(msg);<br /></code></p> <p><span style="color: rgb(0, 0, 255);"><strong>不要方法的名字中重复此方法的类的名称</strong></span><br /><code>Bad:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list.AddToList(item);<br />Good:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list.Add(item);<br /></code></p> <p><span style="color: rgb(0, 0, 255);"><strong>不要在函数的名字中加入返回类型，除非函数名必须以返回类型进行区别</strong></span><br /><code>Bad:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list.GetCountInt();<br />Good:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list.GetCount();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;message.GetIntValue();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;message.GetFloatValue();<br /></code></p> <p><span style="color: rgb(0, 0, 255);"><strong>不要名字中使用And 或则 Or</strong></span><br />如果你使用一个连接词来连接函数名，那么这个函数肯定是做了太多的事情，更好的做法是将其分成更小的函数来处理(类似面向对象设计准则中的责任单一原则)。<br />如果你想确保是这是一个原子的操作，那么你应该用一个名字来描述这个操作或一个类来封装他<br /><code>Bad:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mail.VerifyAddressAndSendStatus();<br />Good:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mail.VerifyAddress();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mail.SendStatus();<br /></code></p> <p>这是一篇非常优秀的文章，我用我的语言在组织了一下，如果喜欢英文的读者可以点击<a href="http://journal.stuffwithstuff.com/2009/06/05/naming-things-in-code/" onclick="pageTracker._trackPageview('/outgoing/journal.stuffwithstuff.com/2009/06/05/naming-things-in-code/?referer=');">这里</a>阅读原文</p><br /><br /><img src ="http://www.blogjava.net/pts/aggbug/282089.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/pts/" target="_blank">pts</a> 2009-06-13 22:50 <a href="http://www.blogjava.net/pts/archive/2009/06/13/282089.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>找到了另外一个图表库：chartDirector for python</title><link>http://www.blogjava.net/pts/archive/2009/06/13/282084.html</link><dc:creator>pts</dc:creator><author>pts</author><pubDate>Sat, 13 Jun 2009 13:54:00 GMT</pubDate><guid>http://www.blogjava.net/pts/archive/2009/06/13/282084.html</guid><wfw:comment>http://www.blogjava.net/pts/comments/282084.html</wfw:comment><comments>http://www.blogjava.net/pts/archive/2009/06/13/282084.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/pts/comments/commentRss/282084.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/pts/services/trackbacks/282084.html</trackback:ping><description><![CDATA[最先是用的matplotlib，但是对中文的支持搞不定<br />找解决办法中，发现了这个<a target="_blank" href="http://wiki.woodpecker.org.cn/moin/ObpLovelyPython/LpyAttach2ResIdx">python资源索引</a>，看到<a target="_blank" href="http://www.advsofteng.com/">chartdirector</a>不错，找介绍，看到了<a target="_blank" href="http://blog.donews.com/limodou/archive/2007/03/06/1137270.aspx">limodou的介绍</a>，好呀，两年前就看到并在django中试了，厉害，不服不行<br /><br /><br /><img src ="http://www.blogjava.net/pts/aggbug/282084.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/pts/" target="_blank">pts</a> 2009-06-13 21:54 <a href="http://www.blogjava.net/pts/archive/2009/06/13/282084.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>cPAMIE模块中使用frame的体会</title><link>http://www.blogjava.net/pts/archive/2009/01/20/252098.html</link><dc:creator>pts</dc:creator><author>pts</author><pubDate>Tue, 20 Jan 2009 11:54:00 GMT</pubDate><guid>http://www.blogjava.net/pts/archive/2009/01/20/252098.html</guid><wfw:comment>http://www.blogjava.net/pts/comments/252098.html</wfw:comment><comments>http://www.blogjava.net/pts/archive/2009/01/20/252098.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/pts/comments/commentRss/252098.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/pts/services/trackbacks/252098.html</trackback:ping><description><![CDATA[以前也用过，这次碰到框架网页，怎么使用也不行，好在是python，查源码，找到了一点办法：<br /><br />先设ie的frameName属性为要操作的框架name<br />然后就可以很自然的使用各个function了<br />要操作其他franme了，再设frameName属性为其他框架的name<br /><br /><br />类似的还有多个form的操作，同样可以先设置formName属性，后续有关的操作如不指定form的话，就是先前设定的那个form<br />（没具体测试，看源码是这么个意思）<br /><img src ="http://www.blogjava.net/pts/aggbug/252098.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/pts/" target="_blank">pts</a> 2009-01-20 19:54 <a href="http://www.blogjava.net/pts/archive/2009/01/20/252098.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]Gems of Python</title><link>http://www.blogjava.net/pts/archive/2008/11/11/239792.html</link><dc:creator>pts</dc:creator><author>pts</author><pubDate>Tue, 11 Nov 2008 01:41:00 GMT</pubDate><guid>http://www.blogjava.net/pts/archive/2008/11/11/239792.html</guid><wfw:comment>http://www.blogjava.net/pts/comments/239792.html</wfw:comment><comments>http://www.blogjava.net/pts/archive/2008/11/11/239792.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/pts/comments/commentRss/239792.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/pts/services/trackbacks/239792.html</trackback:ping><description><![CDATA[<a href="http://www.eflorenzano.com/blog/post/gems-python/">Gems of Python - Eric Florenzano's Website</a><br /><blockquote>Gems of Python<br /><br />    * Tags:<br />    * programming,<br />    * python<br /><br />Posted on Nov. 2, 2008 at 4:04 P.M.<br /><br />I've been using Python for a few years now, and continue to love it. But the language is large enough that it seems every project that I look at uses a different subset of the language's features. The nice thing is that by reading different people's code, you can find out about some real gems in the Python programming language. Some of these tips are extremely obvious, and some are more obscure. In any case, here are what I consider to be some real gems:<br /><br />   1.<br /><br />      filter This is one of Python's built-in functions, which allows you to remove unwanted items from a list. It's very useful and highly overlooked. Here's an example of how to use it:<br /><br />      &gt;&gt;&gt; lst = ['1', '2', '3', '4', 'asdf', '5']<br />      &gt;&gt;&gt; def is_int_string(i):<br />      ...     try:<br />      ...         int(i)<br />      ...         return True<br />      ...     except ValueError:<br />      ...         return False<br />      ...<br />      &gt;&gt;&gt; int_string_list = filter(is_int_string, lst)<br />      &gt;&gt;&gt; int_string_list<br />      ['1', '2', '3', '4', '5']<br /><br />      But there is a really neat filter shortcut, too. You can have it filter out any values which evaluate to False.<br /><br />      &gt;&gt;&gt; lst = [0, 2, '', 'asdf', None, [], (), 'fdsa']<br />      &gt;&gt;&gt; filter(None, lst)<br />      [2, 'asdf', 'fdsa']<br /><br />      This is really great for filtering out unwanted values in a list. I use it actually quite frequently and hope to see it in more python projects.<br />   2.<br /><br />      itertools.chain I often have a list of lists, and want to run some operation on each item in that list of lists. itertools.chain allows that to happen. Let me demonstrate with an example:<br /><br />      &gt;&gt;&gt; import itertools<br />      &gt;&gt;&gt; lst = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]<br />      &gt;&gt;&gt; list(itertools.chain(*lst))<br />      [1, 2, 3, 4, 5, 6, 7, 8, 9]<br />      &gt;&gt;&gt; sum(itertools.chain(*lst))<br />      45<br /><br />      itertools.chain has become a major part of my day-to-day coding toolbox, and it's a real python gem.<br />   3.<br /><br />      setdefault Do you find yourself writing this type of try..except KeyError pattern often?<br /><br />      &gt;&gt;&gt; dct = {}<br />      &gt;&gt;&gt; items = ['anne', 'david', 'kevin', 'eric', 'anthony', 'andrew']<br />      ... for name in items:<br />      ...     try:<br />      ...         dct[name[0]].append(name)<br />      ...     except KeyError:<br />      ...         dct[name[0]] = [name]<br />      &gt;&gt;&gt; dct<br />      {'a': ['anne', 'anthony', 'andrew'], 'k': ['kevin'], 'e': ['eric'], 'd': ['david']}<br /><br />      That's a lot of boilerplate code for something that seems like it should be much easier. Thankfully, this can be solved much more easily by using setdefault, like so:<br /><br />      &gt;&gt;&gt; dct = {}<br />      &gt;&gt;&gt; items = ['anne', 'david', 'kevin', 'eric', 'anthony', 'andrew']<br />      &gt;&gt;&gt; for name in items:<br />      ...     dct.setdefault(name[0], []).append(name)<br />      ...<br />      &gt;&gt;&gt; dct<br />      {'a': ['anne', 'anthony', 'andrew'], 'k': ['kevin'], 'e': ['eric'], 'd': ['david']}<br /><br />      Much better, isn't it?<br />   4.<br /><br />      defaultdict Given setdefault, it still seems like there should be a better way. If you know upfront that you will be setting everything to an empty list if it isn't found, you should be able to specify that and have it just Do The Right Thing. Thankfully, defaultdict does just that:<br /><br />      &gt;&gt;&gt; from collections import defaultdict<br />      &gt;&gt;&gt; dct = defaultdict(list)<br />      &gt;&gt;&gt; items = ['anne', 'david', 'kevin', 'eric', 'anthony', 'andrew']<br />      &gt;&gt;&gt; for name in items:<br />      ...     dct[name[0]].append(name)<br />      ...<br />      &gt;&gt;&gt; dct<br />      defaultdict(<type list="">, {'a': ['anne', 'anthony', 'andrew'], 'k': ['kevin'], 'e': ['eric'], 'd': ['david']})<br />      &gt;&gt;&gt; dict(dct)<br />      {'a': ['anne', 'anthony', 'andrew'], 'k': ['kevin'], 'e': ['eric'], 'd': ['david']}<br /><br />      I usually end up converting the defaultdict back to a regular dict before passing it around, but other than that, it's quite a useful tool to use.<br />   5.<br /><br />      zip This is one that most people usually know, but still I find that sometimes people do strange things where a zip would be much easier.<br /><br />      &gt;&gt;&gt; numbers = [1, 2, 3, 4, 5]<br />      &gt;&gt;&gt; letters = ['a', 'b', 'c', 'd', 'e']<br />      &gt;&gt;&gt; for num, let in zip(numbers, letters):<br />      ...     print "Letter %d is '%s'" % (num, let)<br />      ...<br />      Letter 1 is 'a'<br />      Letter 2 is 'b'<br />      Letter 3 is 'c'<br />      Letter 4 is 'd'<br />      Letter 5 is 'e'<br /><br />      Pretty simple, very common, and yet sometimes coders seem to work around it. Also worth mentioning is that there's an iterable version of this, izip, which is located in itertools.<br />   6.<br /><br />      title I wrote some little function to turn a string of lower case text into a 'titleized' string at work, and a few coworkers laughed and said, "why didn't you just use title"? The answer: I didn't know about it. It's not something you run into every day, but when you need it, it's super useful. Here's an example:<br /><br />      &gt;&gt;&gt; s = 'the little green men'<br />      &gt;&gt;&gt; s.title()<br />      'The Little Green Men'<br /><br />      It's that easy! Next time you need to turn something into a title, look for this method on strings first.<br /><br />That's all I've got for now. There are many more gems in the Python programming language, but these are some that I think are especially useful. Please share in the comments if you have any other gems that you have found in your uses of Python.<br /><br />UPDATE: Eric Holscher has posted a list of his Python gems as well, and it's got some great stuff on it. Check it out!</type></blockquote><img src ="http://www.blogjava.net/pts/aggbug/239792.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/pts/" target="_blank">pts</a> 2008-11-11 09:41 <a href="http://www.blogjava.net/pts/archive/2008/11/11/239792.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]推荐几个有难度的编程网站</title><link>http://www.blogjava.net/pts/archive/2008/10/24/236341.html</link><dc:creator>pts</dc:creator><author>pts</author><pubDate>Fri, 24 Oct 2008 02:27:00 GMT</pubDate><guid>http://www.blogjava.net/pts/archive/2008/10/24/236341.html</guid><wfw:comment>http://www.blogjava.net/pts/comments/236341.html</wfw:comment><comments>http://www.blogjava.net/pts/archive/2008/10/24/236341.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/pts/comments/commentRss/236341.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/pts/services/trackbacks/236341.html</trackback:ping><description><![CDATA[<a href="http://blog.csdn.net/lanphaday/archive/2008/10/23/3132815.aspx">推荐几个好玩又有难度的编程网站 - 赖勇浩（恋花蝶）的博客</a><br /><br />在社区混久了，总看到许多新朋友问“我学会了XX语言，怎么深入（或能用它做点什么）？”今天我给大家推荐几个好玩又有难度的编程网站，它们不仅可以增进对语言特性的了解，而且可以激发起大家对数学和算法等基础学科的兴趣，有些甚至还可以赚钱、帮你找工作呢！<br /><br /><br />这于这类网站，第一个要推荐的当然是 project euler，它的地址是：http://projecteuler.net/。它现在已经有两百多道题了，几乎每个周未都会出一两题新题。前面的题会比较简单，而后越来越难。在这个网站玩，必须要数学和编程技能都吃得开才行，好在这个网站并不看过程，只看结果，所以你可以用你最熟悉的编程语言来解决问题。但它提倡一个著名的一分钟原则，即“你解决某一道题的程序在一台主流 PC 运行时间不应多于一分钟”。另外值得称道的是如果你写的代码很牛，论坛是一个很好的炫耀你华丽的代码的好地方；反过来说，论坛可以让你学到许多语言特性、技巧、算法，还有最重要的数学。<br /><br />我们可以来看看 project euler 的第一道题：<br /><br />If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23. Find the sum of all the multiples of 3 or 5 below 1000.<br /><br />它的解决方案用 python 语言写出来是：<br /><br />print sum(i for i in xrange(1, 1000) if i % 3 == 0 or i % 5 == 0)<br /><br /><br />作为一个 pythoner，要找好玩的编程网站的话，pythonchallenge.com（http://www.pythonchallenge.com/） 是不容错失的。用沈崴（http://blog.163.com/eishn/）的话来说，它的功效是：我们部门新来两位同事, 在使用 Python 做项目之前, 先沉下心来做了两周的 Python Challenge, 把 Python 模了个透, 结果两周后程序写出来相当漂亮, 甚至让我这种老牌 Python 程序员跌破眼镜, 与我周围的同事立马有了境界上的区分。<br /><br />这个网站不仅考验你的数学、算法功底，而且需要比较高的智商。不过，最为重要的是你需要一个像 python 这样的强大的语言，看到上面那幅图片了吗？它是 pythonchallenge 的第一道题，简单地说，就是叫你计算 2 的 38 次方。解决这样的问题用 python 只需要一行代码，5 个字符，你用 C/C++ 的话，哈哈……<br /><br /><br />另外一个好玩的网站是 code golf（http://codegolf.com/），它的方向比较不同，它倡导短代码。立志于一行写出一个 windows 来的朋友们当然一定要去看看了，不过说到代码短，perl 可能真的很有优势。这个网站接受 PHP、Python和 ruby，也许它更适合于网络程序员？无论如何，这是另一个能够让你炫耀编程技巧的平台，值得去看看。<br /><br /><br />好吧，仅仅挑战智商的东西你提不起兴趣，你希望得到一些实质性的收益，比如金钱、经验或工作机会，那 topcoder.com（http://www.topcoder.com/） 一定适合你！无论国内还是国外，算法狂人都喜欢去 topcoder 比赛，因为它不仅有难度，而且有丰厚的奖品。如果还是学生，玩 SRM 最是刺激，如果白天你已经有一份工作要忙，那么玩一下 marathon，在长达一周或者两周的时间里，尝试一下持续的优化快感，感觉棒极了！实不相瞒，我是毕业以后才知道这样的一个网站的，偶尔我也会去玩一下 marathon，但最近一年多，我已经没有这个精力了，好想回到学生时代，让我享受一下 topcoder 带来的挑战。<br /><br />Topcoder 的另一个好处是不仅支持 C++、java、python等语言，而且完美支持微软系的语言，如 VB.net、C# 等，可以说是最为大众化了。它的中文站地址是http://www.topcoderchina.com/。但看上去有点荒废许久的感觉了，不知道当年很热的美少女副总吴莹莹现在在忙啥呢？<br /><br />发表于 @ 2008年10月23日 23:40:00<img src ="http://www.blogjava.net/pts/aggbug/236341.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/pts/" target="_blank">pts</a> 2008-10-24 10:27 <a href="http://www.blogjava.net/pts/archive/2008/10/24/236341.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转] 理解python中的method与function</title><link>http://www.blogjava.net/pts/archive/2008/10/15/234433.html</link><dc:creator>pts</dc:creator><author>pts</author><pubDate>Wed, 15 Oct 2008 06:21:00 GMT</pubDate><guid>http://www.blogjava.net/pts/archive/2008/10/15/234433.html</guid><wfw:comment>http://www.blogjava.net/pts/comments/234433.html</wfw:comment><comments>http://www.blogjava.net/pts/archive/2008/10/15/234433.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/pts/comments/commentRss/234433.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/pts/services/trackbacks/234433.html</trackback:ping><description><![CDATA[转自：<a href="http://codeplayer.blogspot.com/search/label/python?max-results=20">白菜: python</a><br />
<br />
总是看到有人对 python 中的 method 和 function 之间关系的困惑，其实初学 python 时我也困惑过，不过现在自认为对这个问题还是基本清楚了 ;-)。<br />
<br />
我在前面写过的 selfless python 里面说过 method 本质上就是 function，这个从它们的形式上也看得出来，呵呵，而让人困惑的问题主要就是那个隐式传入的 self 参数。这其实是利用了descriptor 机制，请看代码：<br />
<br />
/&gt;&gt;&gt; class Temp(object):<br />
...   def test(self, a):<br />
...     print self, a<br />
...<br />
/&gt;&gt;&gt; func = Temp.__dict__['test']<br />
/&gt;&gt;&gt; func<br />
<function test="" at="" 0x00b48170=""><br />
/&gt;&gt;&gt; func(1, 2)<br />
1 2<br />
<br />
由此可见 test 就是个不折不扣的函数！<br />
<br />
/&gt;&gt;&gt; Temp.test<br />
<unbound method=""  temp.="" test=""><br />
/&gt;&gt;&gt; t = Temp()<br />
/&gt;&gt;&gt; t.test<br />
<bound method=""  temp.="" test="" of="">&lt;__main__.Temp object at 0x00B46CD0&gt;&gt;<br />
<br />
但是这又是怎么回事了？哪里冒出个 bound/unbound method 来了？<br />
<br />
/&gt;&gt;&gt; dir(func)<br />
['__call__', '__class__', '__delattr__', '__dict__', '__doc__', '__get__', '__ge<br />
tattribute__', '__hash__', '__init__', '__module__', '__name__', '__new__', '__r<br />
educe__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', 'func_closure',<br />
'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals', 'func_na<br />
me']<br />
<br />
请注意其中的 __get__ 方法，这就是 descriptor 的标志(任何定义了 __get__, __set__, __delete__ 三个方法中的一个或几个的对象都是 descriptor ，这几个方法的意思大家应该能猜到了)<br />
<br />
根据对象 attribute 的查找策略，当 t.test 时，首先根据 attribute查找策略找到这个函数对象，然后会发现它有 __get__ 属性，则调用之，并把它的返回值当作该 attribute 的值。<br />
<br />
Temp.test 等价于 Temp.__dict__['test'].__get__(None, Temp)<br />
t.test    等价于 Temp.__dict__['test'].__get__(t, Temp)<br />
<br />
其实你可以把 func.__get__ 的实现想象成下面这个等价物：<br />
<br />
/&gt;&gt;&gt; class Function(object):<br />
...     def __get__(self, obj, objtype=None):<br />
...         import types<br />
...         return types.MethodType(self, obj, objtype)<br />
<br />
到这里事情已经比较清楚了，不过还有一点可能仍然会让你感到困惑：<br />
<br />
/&gt;&gt;&gt; Temp.test = test<br />
<br />
/&gt;&gt;&gt; t.test(1)<br />
&lt;__main__.Temp object at 0x00B46E90&gt; 1<br />
/&gt;&gt;&gt; t.test = test<br />
/&gt;&gt;&gt; t.test(1)<br />
Traceback (most recent call last):<br />
File "<stdin>", line 1, in ?<br />
TypeError: test() takes exactly 2 arguments (1 given)<br />
/&gt;&gt;&gt; t.test<br />
<function test="" at="" 0x00b42a30=""><br />
<br />
咦？不是说 function 是 descriptor 的吗？怎么这里没有去调用它的 __get__ 方法呢？<br />
<br />
另外：<br />
<br />
/&gt;&gt;&gt; class Meta(type):pass<br />
...<br />
/&gt;&gt;&gt; class Temp(object):<br />
...   __metaclass__ = Meta<br />
...<br />
/&gt;&gt;&gt; class Desc(object):<br />
...   def __get__(self, instance, type):<br />
...     print instance, type<br />
...<br />
/&gt;&gt;&gt; desc = Desc()<br />
/&gt;&gt;&gt; Meta.d = desc<br />
/&gt;&gt;&gt; Meta.d<br />
None <class __main__.="" meta=""><br />
<br />
/&gt;&gt;&gt; Temp.d<br />
<class __main__.="" temp=""> <class __main__.="" meta=""><br />
/&gt;&gt;&gt; Temp.d = desc<br />
/&gt;&gt;&gt; Temp.d<br />
None <class __main__.="" temp=""><br />
/&gt;&gt;&gt; t = Temp()<br />
/&gt;&gt;&gt; t.d<br />
&lt;__main__.Temp object at 0x00B46DD0&gt; <class __main__.="" temp=""><br />
<br />
/&gt;&gt;&gt; t.d = desc<br />
/&gt;&gt;&gt; t.d<br />
&lt;__main__.Desc object at 0x00B46D30&gt;<br />
<br />
注意到，到最后一步 t.d 的时候也没有对 descriptor 求值。这个道理和上面那个是一样的，仔细看一下 attribute 查找策略 就可以找到答案了， descriptor 只有绑定在 type object 上才有效。<br />
<br />
这里我们涉及到了 python对象一种分类： type object 和 非 type object ，这两种对象在 attribute 查找过程中的待遇是不一样的。<br />
<br />
简单地说 type object 包括 type, type 的子类( 也就是 metaclass 了 )、 type 的实例( 也就是 class 了 )<br />
<br />
一般来说 type object 和 非 type object 不光在 attribute 受到不平等待遇，而且非 type object 还不能成为其它对象的基类型，想成为 metaclass 更是痴心妄想了。<br />
<br />
不过就像我以前说过的那样，python 中的对象本质上都是平等的，区分它们的唯一方法是它们的接口，所以我相信所谓 type object 与 非 type object 的区别也只在于接口而已。也就是说只要实现 type object 所需的接口，任何对象都可以成为 type object 。<br />
<br />
参考：<br />
<br />
How-To Guide for Descriptors<br />
Python Attributes and Methods<br />
<br />
</class></class></class></class></class></function></stdin></bound></unbound></function>
<img src ="http://www.blogjava.net/pts/aggbug/234433.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/pts/" target="_blank">pts</a> 2008-10-15 14:21 <a href="http://www.blogjava.net/pts/archive/2008/10/15/234433.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>python 学习资料</title><link>http://www.blogjava.net/pts/archive/2008/10/15/234340.html</link><dc:creator>pts</dc:creator><author>pts</author><pubDate>Wed, 15 Oct 2008 00:27:00 GMT</pubDate><guid>http://www.blogjava.net/pts/archive/2008/10/15/234340.html</guid><wfw:comment>http://www.blogjava.net/pts/comments/234340.html</wfw:comment><comments>http://www.blogjava.net/pts/archive/2008/10/15/234340.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.blogjava.net/pts/comments/commentRss/234340.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/pts/services/trackbacks/234340.html</trackback:ping><description><![CDATA[<pre>摘自&lt;a href="http://www.woodpecker.org.cn/obp/pages.wiki.woodpecker/PythonLanguage/revisions/00000022" target="_blank"&gt;啄木鸟社区&lt;/a&gt;<br />
（找到的原文是rst格式）<br />
</pre>
Python 语言研究 <br />
<blockquote><br />
== 概述 ==<br />
<br />
. 对于一种编程语言来说，语法格式是其最直观的表现，各种类库的 API 是其最直接的应用。<br />
. 但在水面之下，语言的基础设施、模型、原理以及背后的设计思想才是其最本质的部分，也是一种语言真正区别于另一种的所在。<br />
. 此条目关注 Python 本身语言、语法的研究和探讨，收集整理相关的文档和心得（尤其是中文资料）。<br />
. 如无特别注明，均以 CPython 实现为准。<br />
<br />
== 系统学习 ==<br />
<br />
* 参见[:PyBooks:Python 图书概览]<br />
. 对于语言特性的学习来说，特别推荐以下几本<br />
* 《Python Tutorial》（最新版本2.5） -- 最新，最权威，公开文档<br />
* 《A Byte of Python》 --  简洁明了，浅显易懂，公开文档<br />
* 《Learning Python》（第二版） -- 最细致，最深入<br />
* 《Text Process in Python》的附录A ：[:TPiP/AppendixA:python精要]<br />
. &#8220;对 python 的超精简的但绝不失深度的介绍&#8221; -- from 译者 HuangYi<br />
<br />
== 语言进化 ==<br />
<br />
* [http://docs.python.org/dev/whatsnew/whatsnew25.html What's New in Python 2.5]<br />
* [http://www.aleax.it/Python/py25.pdf Python 2.5 Slides by Alex Martelli]<br />
* [:WeiZhong/WhatsNewOfPython25:WeiZhong 节译]<br />
* [:PythoNology/New4Py2.5:ZoomQuiet 译自另一篇文档]<br />
<br />
* [http://docs.python.org/dev/whatsnew/ What's New in Python 2.6]<br />
<br />
* [:Python3000:Python 3000 专题] -- 收集了 Python 3000 的规范、展望和最新消息<br />
<br />
== 专题剖析 ==<br />
<br />
=== 内置类型和操作 ===<br />
<br />
* [http://www.voidspace.org.uk/python/articles/python_datatypes.shtml A Very Brief Introduction to Python And its Data-Types]<br />
. &#8220;一篇短小精悍的 python tutorial 。对一些容易被忽视的问题讲得很清楚！很专业的 tutorial！&#8221; -- from HuangYi<br />
<br />
* [http://blog.donews.com/limodou/archive/2004/05/11/18038.aspx 集合(sets)模块] from [http://blog.donews.com/limodou/ limodou 的学习记录] <br />
. 在 2.4 以后，sets 模块已经成为内置类型 set<br />
<br />
=== 语句和语法 ===<br />
<br />
==== 自省 ====<br />
* [http://www.ibm.com/developerworks/cn/linux/l-pyint/index1.html Python 自省指南]、[http://www.ibm.com/developerworks/cn/linux/l-pyint/index2.html （二）] （原网页上&#8220;下一页&#8221;链接有误）<br />
. 发表于 IBM developerWorks 网站，作者 Patrick O'Brien 是 Py``Crust 的作者，此为中文版。<br />
<br />
* [:PyBatteriesIncluded:内省的威力]<br />
<br />
==== Iterator、Generator 和 yield ====<br />
* [http://www.ibm.com/developerworks/cn/linux/sdk/python/charm-20/index.html 可爱的 Python: 迭代器和简单生成器——Python 2.2 中的新型构造]<br />
* [http://www.ibm.com/developerworks/cn/linux/sdk/python/charm-25/index.html 可爱的 Python: 用 Python 生成器实现&#8220;轻便线程&#8221;——微线程的力量]<br />
* [http://www.ibm.com/developerworks/cn/linux/sdk/python/charm-26/index.html 可爱的 Python: 基于生成器的状态机——用基于生成器的状态机和协同程序增加效率]<br />
. 以上三篇均为 David Mertz 的 developerWorks Python 专栏文章<br />
<br />
* [http://blog.donews.com/limodou/archive/2004/07/10/40913.aspx Iterator 和 Generator的学习心得] by limodou<br />
<br />
* [:Py25yieldNote:Py2.5 yield 详说] -- shhgs 和 limodou 关于 yield 在2.5中加强语法的探讨<br />
* [:HuangYi/yield_stacklesspython:用 2.5 中的 yield 模拟 Stackless Python] by HuangYi<br />
. 可与[http://www.ibm.com/developerworks/cn/linux/sdk/python/charm-25/index.html 《用 Python 生成器实现&#8220;轻便线程&#8221;》]对照，加强的 yield 语法带来了更强大的力量和更灵活的运用<br />
<br />
==== Decorator ====<br />
* [wiki:peps/pep-0318/ PEP 318 : Decorators for Functions and Methods]<br />
* [:WeiZhong/DecoratorsInPython24:Python2.4中的新东西(1):函数和方法的修饰符]  by WeiZhong<br />
* [http://blog.donews.com/limodou/archive/2004/12/19/207521.aspx decorator的使用] by limodou<br />
* [http://www.donews.net/limodou/archive/2004/12/20/208356.aspx Decorator 应用：使用decorator的线程同步] by limodou<br />
* [http://blog.donews.com/limodou/archive/2004/12/31/221653.aspx 关于阅读《Doing abstract methods with decorators》的思考] by limodou<br />
<br />
==== with ====<br />
<br />
=== 名字空间与对象模型 ===<br />
<br />
==== 概述 ====<br />
* Python 官方网站上的 [http://www.python.org/doc/newstyle/ New-style Classes 经典文档汇集]<br />
<br />
* [http://www.effbot.org/zone/python-objects.htm Python Objects]<br />
. Python 对象概念简析 —— 比你想像中更简单！<br />
<br />
* 两篇系统讲解的精彩文档<br />
* [http://www.cafepy.com/article/python_types_and_objects Python Types and Objects]<br />
* [http://www.cafepy.com/article/python_attributes_and_methods/ Python Attributes and Methods]<br />
<br />
* [:PyNewStyleClass:Python 中的新型类及其实例详解] -- WeiZhong 节译自《Python in a Nutshell》（第一版）<br />
<br />
* [http://blog.csdn.net/jrgao/archive/2004/03/04/22248.aspx python的对象与名字绑定]、[http://blog.csdn.net/dreamingk/archive/2004/07/26/51658.aspx 对于"python的对象与名字绑定"一文错误的纠正!]<br />
* [http://blog.donews.com/limodou/archive/2005/07/09/460187.aspx 关于Python对象及名字绑定] -- limodou 的补充感想<br />
<br />
==== Metaclass ====<br />
<br />
* [:MetaClassInPython:Python中的元类(metaclass)] -- WeiZhong 节译自《Python in a Nutshell》（第一版）<br />
<br />
* [http://www.ibm.com/developerworks/cn/linux/l-pymeta/index.html Python 中的元类编程]、[http://www.ibm.com/developerworks/cn/linux/l-pymeta2/index.html Python 中的元类编程，第 2 部分]<br />
. 发表于 IBM developerWorks 网站，作者为知名 Python 专栏作家 David Mertz，此为中文版。<br />
<br />
* [http://www.python.org/pycon/dc2004/papers/24/metaclasses-pycon.pdf Python Metaclasses: Who? Why? When?] -- 2004年 Py{{{}}}Con 上的一篇讲稿<br />
<br />
* [http://www.voidspace.org.uk/python/articles/metaclasses.shtml Eliminating self with Metaclasses]<br />
. Python 在成员方法中对 self 的显式声明往往会令初学者困惑和不习惯，Michael Foord 在这篇文章中利用 metaclass 和 bytecode 实现了一种不需要显式声明 self 参数的类定义方式。<br />
<br />
* HuangYi 的心得，发表于[http://codeplayer.blogspot.com 他的 blog]<br />
* [http://codeplayer.blogspot.com/2006/12/metaclass-in-python.html metaclass in python (part 1)]<br />
* [http://codeplayer.blogspot.com/2006/12/metaclass-in-python-part-2.html metaclass in python (part 2)]<br />
<br />
==== Descriptor ====<br />
* [http://users.rcn.com/python/download/Descriptor.htm How-To Guide for Descriptors] -- descriptor 机制详解，by Raymond Hettinger<br />
<br />
* [http://codeplayer.blogspot.com/2006/12/python-method-function-descriptor.html 理解 python 的 method 和 function 兼谈 descriptor] by HuangYi<br />
<br />
==== Magic Methods ====<br />
* [http://blog.donews.com/limodou/archive/2004/10/16/134808.aspx 使用__getattr__要注意的]、[http://blog.donews.com/limodou/archive/2004/10/18/137326.aspx 又一次谈&#8220;使用__getattr__要注意的&#8221;]<br />
. 自定义 __getattr__ 带来的意想不到的副作用， from [http://blog.donews.com/limodou/ limodou 的学习记录]<br />
<br />
=== 模块导入机制 ===<br />
<br />
* [http://www.ibm.com/developerworks/cn/linux/sdk/python/python-8/index.html 可爱的 Python：动态重新装入——在长期运行的进程中动态重新装入模块]<br />
. David Mertz 的 developerWorks Python 专栏文章<br />
* [http://blog.donews.com/limodou/archive/2005/06/10/422024.aspx __import__与reload要注意的] from [http://blog.donews.com/limodou/ limodou 的学习记录] <br />
<br />
=== 异常机制 ===<br />
<br />
=== 其它 ===<br />
* [http://www-128.ibm.com/developerworks/cn/linux/l-pydisp/index.html 可爱的 Python: 多分派——用多元法泛化多态性]<br />
* [http://blog.donews.com/limodou/archive/2004/07/24/49297.aspx 我看&#8220;Python中的多分派&#8221;] -- limodou的感想<br />
* [http://codeplayer.blogspot.com/2006/09/getcaller.html 意外收获：get_caller] by HuangYi<br />
* [http://www.donews.net/limodou/archive/2004/12/28/218443.aspx  Python 中的 Lazy 计算]、[http://blog.donews.com/limodou/archive/2004/12/30/221020.aspx 再谈一谈Lazy计算] from [http://blog.donews.com/limodou/ limodou 的学习记录] <br />
<br />
== 参考 ==<br />
* http://www.python.org/doc/newstyle/<br />
* ["ThinkIntoPython"]<br />
* ["PythonZhDoc"]<br />
* ["PythoNology"]<br />
* http://www.voidspace.org.uk/python/index.shtml<br />
* [http://www.ibm.com/developerworks/cn/linux/theme/special/index.html#python IBM developerWorks 的 Python 专栏]<br />
* [http://blog.donews.com/limodou/ limodou 的学习记录] -- limodou 的 blog<br />
* [http://codeplayer.blogspot.com 白菜] -- HuangYi 的 blog<br />
</blockquote> 
<img src ="http://www.blogjava.net/pts/aggbug/234340.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/pts/" target="_blank">pts</a> 2008-10-15 08:27 <a href="http://www.blogjava.net/pts/archive/2008/10/15/234340.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>google map</title><link>http://www.blogjava.net/pts/archive/2008/05/11/199890.html</link><dc:creator>pts</dc:creator><author>pts</author><pubDate>Sun, 11 May 2008 14:07:00 GMT</pubDate><guid>http://www.blogjava.net/pts/archive/2008/05/11/199890.html</guid><wfw:comment>http://www.blogjava.net/pts/comments/199890.html</wfw:comment><comments>http://www.blogjava.net/pts/archive/2008/05/11/199890.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/pts/comments/commentRss/199890.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/pts/services/trackbacks/199890.html</trackback:ping><description><![CDATA[http://ditu.google.com/maps?f=q&amp;hl=zh-CN&amp;geocode=&amp;q=三门峡<br /><img src ="http://www.blogjava.net/pts/aggbug/199890.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/pts/" target="_blank">pts</a> 2008-05-11 22:07 <a href="http://www.blogjava.net/pts/archive/2008/05/11/199890.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Python数据结构：图的实现（转）</title><link>http://www.blogjava.net/pts/archive/2008/05/05/198580.html</link><dc:creator>pts</dc:creator><author>pts</author><pubDate>Mon, 05 May 2008 14:20:00 GMT</pubDate><guid>http://www.blogjava.net/pts/archive/2008/05/05/198580.html</guid><wfw:comment>http://www.blogjava.net/pts/comments/198580.html</wfw:comment><comments>http://www.blogjava.net/pts/archive/2008/05/05/198580.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/pts/comments/commentRss/198580.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/pts/services/trackbacks/198580.html</trackback:ping><description><![CDATA[<p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">Python</span><span style="font-size: 12pt; font-family: 宋体;">数据结构：图的实现（转）<span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">2008-03-26 15:00<o:p></o:p></span></p>
<p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">原作：<span lang="EN-US"><a href="http://www.python.org/doc/essays/graphs.html"><span style="color: windowtext;">Python.org</span></a><br />
</span>翻译：<strong><span lang="EN-US">nasi</span></strong><span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">图是由边或者弧连接起来的节点的网络。在有向图中，节点之间的连接是有方向的，叫做弧<span lang="EN-US">(arcs)</span>。在无向图中，节点间的连接没有方向，叫做边<span lang="EN-US"> (edge)</span>。图算法包括查找两点间路径、两点间的最短路径、判断一个图中是否存在环<span lang="EN-US">(</span>环是从一个节点可以沿一条非空路径回到它自己<span lang="EN-US">)</span>、找到可以遍历所有 节点的路径<span lang="EN-US">(</span>著名的<span lang="EN-US">TSP</span>问题，即旅行商问题<span lang="EN-US">)</span>等等。有些情况下节点或者图的弧是带有权重<span lang="EN-US">(weight)</span>或者消耗<span lang="EN-US">(cost)</span>的，我们一般需要寻找这类 图上的最小消耗路径。<span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">图算法作为离散数学中的一个重要部分，有很多文献可供参考。图在计算机算法中有很多的应用，一个很明显的例子就是网络管理。而且图还在其它的很多领
域有广泛的应用，再比如在一个计算机程序之内的函数叫与被叫关系就可以看成是一个图，如果出现了环<span lang="EN-US">(cycle)</span>就表示递归，而不能到达的节点就是<span lang="EN-US">&#8220;</span>死代 码<span lang="EN-US">&#8221;</span>。<span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">几乎没有编程语言把图作为一项直接支持的数据类型，<span lang="EN-US">Python</span>也不例外。然而，图很容易通过列表和词典来构造。比如说，这有一张简单的图：<span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">　<span lang="EN-US">A -&gt; B<br />
</span>　<span lang="EN-US">A -&gt; C<br />
</span>　<span lang="EN-US">B -&gt; C<br />
</span>　<span lang="EN-US">B -&gt; D<br />
</span>　<span lang="EN-US">C -&gt; D<br />
</span>　<span lang="EN-US">D -&gt; C<br />
</span>　<span lang="EN-US">E -&gt; F<br />
</span>　<span lang="EN-US">F -&gt; C<o:p></o:p></span></span></p>
<p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><br />
</span><span style="font-size: 12pt; font-family: 宋体;">这个图有<span lang="EN-US">6</span>个节点<span lang="EN-US">(A-F)</span>和<span lang="EN-US">8</span>个弧。它可以通过下面的<span lang="EN-US">Python</span>数据结构来表示：<span lang="EN-US"><br />
graph = {'A': ['B', 'C'],<br />
<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>'B': ['C', 'D'],<br />
<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>'C': ['D'],<br />
<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>'D': ['C'],<br />
<span>&nbsp; </span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span>'E': ['F'],<br />
<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>'F': ['C']}<o:p></o:p></span></span></p>
<p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">这是一个词典，每个<span lang="EN-US">key</span>都是图的节点。每个<span lang="EN-US">key</span>都对应一个列表，列表里面存的是直接通过一个弧和这个节点连接的节点。这个图非常简单了，不过更简单的是用数字来代替字母来表示一个节点。不过用名字<span lang="EN-US">(</span>字母<span lang="EN-US">)</span>来表示很方便，而且也便于扩展，比如可以改成城市的名字等等。<span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">我们来写一个函数来判断两个节点间的路径。它的参数是一个图、一个起始节点和一个终点。它会返回一个列表，列表里面存有组成这条路径的节点<span lang="EN-US">(</span>包括起 点和终点<span lang="EN-US">)</span>。如果两个节点之间没有路径的话，那就返回<span lang="EN-US">None</span>。相同的节点不会在返回的路径中出现两次或两次以上<span lang="EN-US">(</span>就是说不会包括环<span lang="EN-US">)</span>。这个算法用到了一 个很重要的技术，叫做回溯：它会去尝试每一种可能，直到找到结果。<span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal" style="text-align: left;" align="left"><strong><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">def</span></strong><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> find_path(graph,
start, end, path=[]):<br />
<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>path = path + [start]<br />
<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong>if</strong> start == end:<br />
<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong>return</strong> path<br />
<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong>if</strong> <strong>not</strong> graph.has_key(start):<br />
<span>&nbsp; </span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><strong>return</strong> None<br />
<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong>for</strong> node <strong>in</strong> graph[start]:<br />
<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong>if</strong> node <strong>not</strong> <strong>in</strong>
path:<br />
<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>newpath = find_path(graph,
node, end, path)<br />
<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong>if</strong> newpath: <strong>return</strong>
newpath<br />
<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong>return</strong> None<br />
</span><span style="font-size: 12pt; font-family: 宋体;">运行的结果<span lang="EN-US">(</span>上面的那张图<span lang="EN-US">)</span>：<span lang="EN-US"><br />
&gt;&gt;&gt; find_path(graph, 'A', 'D')<br />
</span>　　<span lang="EN-US">['A', 'B', 'C', 'D']<br />
&gt;&gt;&gt;<o:p></o:p></span></span></p>
<p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">代码中的第二个<span lang="EN-US">if</span></span><span style="font-size: 10pt; font-family: 宋体;" lang="EN-US">(</span><span style="font-size: 10pt; font-family: 宋体;">译者注：是指<span lang="EN-US">if not graph.has_key(start):</span>这句<span lang="EN-US">)</span></span><span style="font-size: 12pt; font-family: 宋体;">仅仅在遇到一类 特殊的节点的时候才有用，这类节点有其他的节点指向它，但是它没有任何弧指向其他的节点，所以就并不会在图这个词典中作为<span lang="EN-US">key</span>被列出来。也可以这样来处 理，即这个节点也作为一个<span lang="EN-US">key</span>，但是有一个空的列表来表示其没有指向其他节点的弧，不过不列出来会更好一些。<span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">注意，当我们调用<span lang="EN-US">find_graph()</span>的时候，使用了<span lang="EN-US">3</span>个参数，但是实际上使用了<span lang="EN-US">4</span>个参数：还有一个是当前已经走过的路径。这个参数的默认值是 一个空列表，<span lang="EN-US">&#8220;[]&#8221;</span>，表示还没有节点被访问过。这个参数用来避免路径中存在环<span lang="EN-US">(for</span>循环中的第一个<span lang="EN-US">if</span>语句<span lang="EN-US">)</span>。<span lang="EN-US">path</span>这个参数本身不会修改，我们用<span lang="EN-US"> &#8220;path = path + [start]&#8221;</span>只是创建了一个新的列表。如果我们使用<span lang="EN-US">&#8220;path.append(start)&#8221;</span>的话，那我们就修改了<span lang="EN-US">path</span>的值，这样会产生灾难性后
果了。如果使用元组的话，我们可以保证这个是不会发生的。在使用的时候要写<span lang="EN-US">&#8220;path = path + (start,)&#8221;</span>，注意<span lang="EN-US">&#8220;(start)&#8221;</span>并不是一个单体元组，只是一个括号表达式而已。<span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">很容易修改这个函数来实现返回一个节点到另一个节点的所有路径，而不仅仅只查找第一条路径：<span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"><o:p>&nbsp;</o:p></span></p>
<p class="MsoNormal" style="text-align: left;" align="left"><strong><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">def</span></strong><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US"> find_all_paths(graph,
start, end, path=[]):<o:p></o:p></span></p>
<p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;" lang="EN-US">path = path + [start]<br />
<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong>if</strong> start == end:<br />
<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong>return</strong> [path]<br />
<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong>if</strong> <strong>not</strong> graph.has_key(start):<br />
<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong>return</strong> []<br />
<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>paths = []<br />
<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong>for</strong> node <strong>in</strong> graph[start]:<br />
<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong>if</strong> node <strong>not</strong> <strong>in</strong>
path:<br />
<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>newpaths = find_all_paths(graph,
node, end, path)<br />
<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong>for</strong> newpath <strong>in</strong>
newpaths:<br />
<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>paths.append(newpath)<br />
<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong>return</strong> paths<br />
<br />
&gt;&gt;&gt; find_all_paths(graph, 'A', 'D')<br />
</span><span style="font-size: 12pt; font-family: 宋体;">　　<span lang="EN-US">[['A', 'B', 'C', 'D'], ['A', 'B', 'D'],
['A', 'C', 'D']]<br />
&gt;&gt;&gt;<br />
<br />
</span>还可以改成查找最短路径：<span lang="EN-US"><br />
<br />
<strong>def</strong> find_shortest_path(graph, start, end, path=[]):<br />
<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>path = path + [start]<br />
<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong>if</strong> start == end:<br />
<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong>return</strong> path<br />
<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong>if</strong> <strong>not</strong> graph.has_key(start):<br />
<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong>return</strong> None<br />
<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>shortest = None<br />
<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong>for</strong> node <strong>in</strong> graph[start]:<br />
<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong>if</strong> node <strong>not</strong> <strong>in</strong>
path:<br />
<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>newpath =
find_shortest_path(graph, node, end, path)<br />
<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong>if</strong> newpath:<br />
<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong>if</strong> <strong>not</strong>
shortest <strong>or</strong> len(newpath) &lt; len(shortest):<br />
<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>shortest =
newpath<br />
<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><strong>return</strong> shortest<br />
<br />
</span>运行结果：<span lang="EN-US"><br />
&gt;&gt;&gt; find_shortest_path(graph, 'A', 'D')<br />
</span>　　<span lang="EN-US">['A', 'C', 'D']<o:p></o:p></span></span></p>
<p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">这些函数都非常简单，但是却已经接近最优了<span lang="EN-US">(</span>用<span lang="EN-US">Python</span>写成的代码中<span lang="EN-US">)</span>。在另一篇文章中，我将尝试去分析它们的运行速度，并改进它们的性能。<span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal" style="text-align: left;" align="left"><span style="font-size: 12pt; font-family: 宋体;">另外还可以引入更多的数据抽象：用一个类来表示一个图，并通过各种方法来实现各种算法。如果通过结构化编程来做这个事情的话，其实对代码的效率提升 没什么帮助<span lang="EN-US">(</span>有时恰恰相反<span lang="EN-US">)</span>。很容易把节点或者弧加上一个命名，就可以来解决实际问题了<span lang="EN-US">(</span>比如在地图上查找两个城市中的最短路<span lang="EN-US">)</span>。这个也会在另一篇文章中 讨论。<span lang="EN-US"><o:p></o:p></span></span></p>
<img src ="http://www.blogjava.net/pts/aggbug/198580.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/pts/" target="_blank">pts</a> 2008-05-05 22:20 <a href="http://www.blogjava.net/pts/archive/2008/05/05/198580.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>make django project environment</title><link>http://www.blogjava.net/pts/archive/2008/04/22/194848.html</link><dc:creator>pts</dc:creator><author>pts</author><pubDate>Tue, 22 Apr 2008 10:12:00 GMT</pubDate><guid>http://www.blogjava.net/pts/archive/2008/04/22/194848.html</guid><wfw:comment>http://www.blogjava.net/pts/comments/194848.html</wfw:comment><comments>http://www.blogjava.net/pts/archive/2008/04/22/194848.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/pts/comments/commentRss/194848.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/pts/services/trackbacks/194848.html</trackback:ping><description><![CDATA[import sys,os <br />
sys.path.append('/path/to/root/of/django/projects/') <br />
os.environ['DJANGO_SETTINGS_MODULE'] = 'myproject.settings'
<img src ="http://www.blogjava.net/pts/aggbug/194848.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/pts/" target="_blank">pts</a> 2008-04-22 18:12 <a href="http://www.blogjava.net/pts/archive/2008/04/22/194848.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]正则表达式30分钟入门教程</title><link>http://www.blogjava.net/pts/archive/2008/04/07/191353.html</link><dc:creator>pts</dc:creator><author>pts</author><pubDate>Mon, 07 Apr 2008 12:11:00 GMT</pubDate><guid>http://www.blogjava.net/pts/archive/2008/04/07/191353.html</guid><wfw:comment>http://www.blogjava.net/pts/comments/191353.html</wfw:comment><comments>http://www.blogjava.net/pts/archive/2008/04/07/191353.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/pts/comments/commentRss/191353.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/pts/services/trackbacks/191353.html</trackback:ping><description><![CDATA[<h1>则表达式30分钟入门教程</h1>
<p id="meta">
版本：v2.21 (2007-8-3) 作者：<a href="http://www.unibetter.com/members/deerchao.aspx">deerchao</a> 来源:<a href="http://www.unibetter.com/">unibetter大学生社区</a><br />
</p>
<h2 id="contents">目录</h2>
<ol>
    <li><a href="http://www.unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#mission">本文目标</a></li>
    <li><a href="http://www.unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#howtouse">如何使用本教程</a></li>
    <li><a href="http://www.unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#introduction">正则表达式到底是什么？</a></li>
    <li><a href="http://www.unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#getstarted">入门</a></li>
    <li><a href="http://www.unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#testing">测试正则表达式</a></li>
    <li><a href="http://www.unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#metacode">元字符</a></li>
    <li><a href="http://www.unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#escape">字符转义</a></li>
    <li><a href="http://www.unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#repeat">重复</a></li>
    <li><a href="http://www.unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#charclass">字符类</a></li>
    <li><a href="http://www.unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#negation">反义</a></li>
    <li><a href="http://www.unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#alternative">替换</a></li>
    <li><a href="http://www.unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#grouping">分组</a></li>
    <li><a href="http://www.unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#backreference">后向引用</a></li>
    <li><a href="http://www.unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#lookaround">零宽断言</a></li>
    <li><a href="http://www.unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#negativelookaround">负向零宽断言</a></li>
    <li><a href="http://www.unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#commenting">注释</a></li>
    <li><a href="http://www.unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#greedyandlazy">贪婪与懒惰</a></li>
    <li><a href="http://www.unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#regexoptions">处理选项</a></li>
    <li><a href="http://www.unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#balancedgroup">平衡组/递归匹配</a></li>
    <li><a href="http://www.unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#more">还有些什么东西没提到</a></li>
    <li><a href="http://www.unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#contact">联系作者</a></li>
    <li><a href="http://www.unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#ad">最后,来点广告...</a></li>
    <li><a href="http://www.unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#reference">一些我认为你可能已经知道的术语的参考</a></li>
    <li><a href="http://www.unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#resources">网上的资源及本文参考文献</a></li>
    <li><a href="http://www.unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#updatelog">更新说明</a></li>
</ol>
<h2 id="mission">
本文目标</h2>
<p>
30分钟内让你明白正则表达式是什么，并对它有一些基本的了解，让你可以在自己的程序或网页里使用它。</p>
<h2 id="howtouse">
如何使用本教程</h2>
<p class="important">
最重要的是——请给我<em>30分钟</em>，如果你没有使用正则表达式的经验，请不要试图在30<em>秒</em>内入门。当然，如果你是超人，那自然得另当别论。</p>
<p>
别被下面那些复杂的表达式吓倒，只要跟着我一步一步来，你会发现正则表达式其实并<span lang="zh-cn">没有</span>你
想像中的那么困难。当然，如果你看完了这篇教程之后，发现自己明白了很多，却又几乎什么都记不得，那也是很正常的——我认为，没接触过正则表达式的人在看
完这篇教程后，能把提到过的语法记住80%以上的可能性为零。这里只是让你明白基本的原理，以后你还需要多练习，多使用，才能熟练掌握正则表达式。</p>
<p>
除了作为入门教程之外，本文还试图成为可以在日常工作中使用的正则表达式语法参考手册。就作者本人的经历来说，这个目标还是完成得不错的——你看，我自己也没能把所有的东西记下来，不是吗？</p>
<p>
文本格式约定：<span class="name">专业术语</span>&nbsp;<span class="code">元字符/语法格式</span>&nbsp;<span class="regex">正则表达式</span>&nbsp;<span class="part">正则表达式中的一部分(用于分析)</span>&nbsp;<span class="string">用于在其中搜索的字符串</span>&nbsp;<span class="desc">对正则表达式或其中一部分的说明</span><a href="http://www.unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm" id="clearButton" accesskey="c" onclick="return clearFormats();">清除格式</a></p>
<h2 id="introduction">
正则表达式到底是什么？</h2>
<p>
在编写处理字符串的程序或网页时，经常会有查找符合某些复杂规则的字符串的需要。<span class="name">正则表达式</span>就是用于描述这些规则的工具。换句话说，正则表达式就是记录文本规则的代码。</p>
<p>
很可能你使用过Windows/Dos下用于文件查找的<span class="name">通配符(wildcard)</span>，也就是<span class="code">*</span>和<span class="code">?</span>。如果你想查找某个目录下的所有的Word文档的话，你会搜索<span style="color: red;">*.doc</span>。在这里，<span class="code">*</span>会被解释成任意的<a href="http://www.unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#reference" title="参考">字符串</a>。和通配符类似，正则表达式也是用来进行<a href="http://www.unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#reference" title="参考">文本</a><a href="http://www.unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#reference" title="参考">匹配</a>的工具，只不过比起通配符，它能更精确地描述你的需求——当然，代价就是更复杂——比如你可以编写一个正则表达式，用来查找<span class="desc">所有以0开头，后面跟着2-3个数字，然后是一个连字号&#8220;-&#8221;，最后是7或8位数字的字符串</span>(像<span class="string">010-12345678</span>或<span class="string">0376-7654321</span>)。</p>
<p id="match">
正则表达式是用于进行文本匹配的工具，所以本文里多次提到了在字符串里搜索/查找，这种说法的意思是在给定的字符串中，寻找与给定的正则表达式相匹配的部分。有可能字符串里有不止一个部分满足给定的正则表达式，这时每一个这样的部分被称为一个匹配。<span class="name">匹配</span>在本文里可能会有三种意思：一种是形容词性的，比如说一个字符串匹配一个表达式；一种是动词性的，比如说在字符串里匹配正则表达式；还有一种是名词性的，就是刚刚说到的&#8220;字符串中满足给定的正则表达式的一部分&#8221;。</p>
<h2 id="getstarted">
入门</h2>
<p>
学习正则表达式的最好方法是从例子开始，理解例子之后再自己对例子进行修改，实验。下面给出了不少简单的例子，并对它们作了详细的说明。</p>
<p>
假设你在一篇英文小说里查找<span class="desc">hi</span>，你可以使用正则表达式<span class="regex">hi</span>。</p>
<p>
这是最简单的正则表达式了，它可以精确匹配这样的字符串：<span class="desc">由两个字符组成，前一个字符是h,后一个是i</span>。通常，处理正则表达式的工具会提供一个忽略大小写的选项，如果选中了这个选项，它可以匹配<span class="string">hi</span>,<span class="string">HI</span>,<span class="string">Hi</span>,<span class="string">hI</span>这四种情况中的任意一种。</p>
<p>
不幸的是，很多单词里包含<span class="string">hi</span>这两个连续的字符，比如<span class="string">him</span>,<span class="string">history</span>,<span class="string">high</span>等等。用<span class="regex">hi</span>来查找的话，这里边的<span class="string">hi</span>也会被找出来。如果要<span class="desc">精确地查找hi这个单词</span>的话，我们应该使用<span class="regex">\bhi\b</span>。</p>
<p>
<span class="part">\b</span>是正则表达式规定的一个特殊代码（好吧，某些人叫它<span class="name">元字符，metacharacter</span>），代表着<span class="desc">单词的开头或结尾，也就是单词的分界处</span>。虽然通常英文的单词是由空格或标点符号或换行来分隔的，但是<span class="code">\b</span>并不匹配这些单词分隔符中的任何一个，它<strong>只匹配一个位置</strong>。（如果需要更精确的说法，<span class="code">\b</span>匹配这样的位置：它的前一个字符和后一个字符不全是(一个是,一个不是或不存在)<span class="code">\w</span>）</p>
<p>
假如你要找的是<span class="desc">hi后面不远处跟着一个Lucy</span>，你应该用<span class="regex">\bhi\b.*\bLucy\b</span>。</p>
<p>
这里，<span class="part">.</span>是另一个元字符，匹配<span class="desc">除了换行符以外的任意字符</span>。<span class="part">*</span>同样是元字符，不过它代表的不是字符，也不是位置，而是数量——它指定*<span class="desc">前边的内容可以连续重复出现任意次以使整个表达式得到匹配</span>。因此，<span class="part">.*</span>连在一起就意味着<span class="desc">任意数量的不包含换行的字符</span>。现在<span class="regex">\bhi\b.*\bLucy\b</span>的意思就很明显了：<span class="desc">先是一个单词hi,然后是任意个任意字符(但不能是换行)，最后是Lucy这个单词</span>。</p>
<p>
如果同时使用其它的一些元字符，我们就能构造出功能更强大的正则表达式。比如下面这个例子：</p>
<p>
<span class="regex">0\d\d-\d\d\d\d\d\d\d\d</span>匹配这样的字符串：<span class="desc">以0开头，然后是两个数字，然后是一个连字号&#8220;-&#8221;，最后是8个数字</span>(也就是中国的电话号码。当然，这个例子只能匹配区号为3位的情形)。</p>
<p>
这里的<span class="part">\d</span>是一个新的元字符，匹配<span class="desc">任意的数字(0，或1，或2，或&#8230;&#8230;)</span>。<span class="part">-</span>不是元字符，只匹配它本身——连字号。</p>
<p>
为了避免那么多烦人的重复，我们也可以这样写这个表达式：<span class="regex">0\d{2}-\d{8}</span>。
这里<span class="part">\d</span>后面的<span class="part">{2}</span>(<span class="part">{8}</span>)的意思是前面<span class="part">\d</span><span class="desc">必须连续重复匹配2次(8次)</span>。</p>
<h2 id="testing">
测试正则表达式</h2>
<p>
如果你不觉得正则表达式很难读写的话，要么你是一个天才，要么，你不是地球人。正则表达式的语法很令人头疼，即使对经常使用它的人来说也是如此。由于难于读写，容易出错，所以很有必要创建一种工具来测试正则表达式。</p>
<p>
由于在不同的环境下正则表达式的一些细节是不相同的，本教程介绍的是Microsoft .Net 2.0下正则表达式的行为，所以，我向你介绍一个.Net下的工具<a title="转到RegexTester的官方网站（英文）" href="http://www.dotnet2themax.com/blogs/fbalena/PermaLink,guid,13bce26d-7755-441e-92b3-1eb5f9e859f9.aspx">Regex
Tester</a>。首先你确保已经安装了<a href="http://www.microsoft.com/downloads/details.aspx?displaylang=zh-cn&amp;FamilyID=0856eacb-4362-4b0d-8edd-aab15c5e04f5" title="转到下载.Net Framework 2.0的页面">.Net Framework 2.0</a>，然后<a href="http://www.unibetter.com/deerchao/downloads/RegexTester.zip" title="从www.unibetter.com下载Regex Tester, 75KB">下载Regex Tester</a>。这是个绿色软件，下载完后打开压缩包,直接运行RegexTester.exe就可以了。</p>
<p>
下面是Regex Tester运行时的截图：</p>
<p>
<img src="http://www.unibetter.com/deerchao/images/RegexTester.jpg" alt="Regex Tester运行时的截图" /></p>
<h2 id="metacode">
元字符</h2>
<p>
现在你已经知道几个很有用的元字符了，如<span class="code">\b</span>,<span class="code">.</span>,<span class="code">*</span>，还有<span class="code">\d</span>.当然还有更多的元字符可用，比如<span class="code">\s</span>匹配<span class="desc">任意的空白符，包括空格，制表符(Tab)，换行符，中文全角空格等</span>。<span class="code">\w</span>匹配<span class="desc">字母或数字或下划线或汉字等</span>。</p>
<p>
下面来试试更多的例子：</p>
<p>
<span class="regex">\ba\w*\b</span>匹配<span class="desc">以字母<span class="part">a</span>开头的单词——先是某个单词开始处(<span class="part">\b</span>)，然后是字母<span class="part">a</span>,然后是任意数量的字母或数字(<span class="part">\w*</span>)，最后是单词结束处(<span class="part">\b</span>)</span>（好吧，现在我们说说正则表达式里的单词是什么意思吧：就是几个连续的<span class="code">\w</span>。不错，这与学习英文时要背的成千上万个同名的东西的确关系不大）。</p>
<p>
<span class="regex">\d+</span>匹配<span class="desc">1个或更多连续的数字</span>。这里的<span class="part">+</span>是和<span class="code">*</span>类似的元字符，不同的是<span class="code">*</span>匹配<span class="desc">重复任意次(可能是0次)</span>，而<span class="code">+</span>则匹配<span class="desc">重复1次或更多次</span>。</p>
<p>
<span class="regex">\b\w{6}\b</span> 匹配<span class="desc">刚好6个字母/数字的单词</span>。</p>
<table cellspacing="0">
    <caption>
    表1.常用的元字符</caption>
    <tbody>
        <tr>
            <th>
            代码</th>
            <th>
            说明</th>
        </tr>
        <tr>
            <td>
            <span class="code">.</span></td>
            <td>
            <span class="desc">匹配除换行符以外的任意字符</span></td>
        </tr>
        <tr>
            <td>
            <span class="code">\w</span></td>
            <td>
            <span class="desc">匹配字母或数字或下划线或汉字</span></td>
        </tr>
        <tr>
            <td>
            <span class="code">\s</span></td>
            <td>
            <span class="desc">匹配任意的空白符</span></td>
        </tr>
        <tr>
            <td>
            <span class="code">\d</span></td>
            <td>
            <span class="desc">匹配数字</span></td>
        </tr>
        <tr>
            <td>
            <span class="code">\b</span></td>
            <td>
            <span class="desc">匹配单词的开始或结束</span></td>
        </tr>
        <tr>
            <td>
            <span class="code">^</span></td>
            <td>
            <span class="desc">匹配字符串的开始</span></td>
        </tr>
        <tr>
            <td>
            <span class="code">$</span></td>
            <td>
            <span class="desc">匹配字符串的结束</span></td>
        </tr>
    </tbody>
</table>
<p>
元字符<span class="code">^</span>（和数字6在同一个键位上的符号）以及<span class="code">$</span>和<span class="code">\b</span>有点类似，都匹配一个位置。<span class="code">^</span>匹配你要用来查找的字符串的开头，<span class="code">$</span>匹配结尾。这两个代码在验证输入的内容时非常有用，比如一个网站如果要求你填写的QQ号必须为5位到12位数字时，可以使用：<span class="regex">^\d{5,12}$</span>。</p>
<p>
这里的<span class="part">{5,12}</span>和前面介绍过的<span class="part">{2}</span>是类似的，只不过<span class="part">{2}</span>匹配<span class="desc">只能不多不少重复2次</span>，<span class="part">{5,12}</span>则是<span class="desc">重复的次数不能少于5次，不能多于12次</span>，否则都不匹配。</p>
<p>
因为使用了<span class="part">^</span>和<span class="part">$</span>，所以输入的整个字符串都要用来和<span class="part">\d{5,12}</span>来匹配，也就是说整个输入<span class="desc">必须是5到12个数字</span>，因此如果输入的QQ号能匹配这个正则表达式的话，那就符合要求了。</p>
<p>
和忽略大小写的选项类似，有些正则表达式处理工具还有一个处理多行的选项。如果选中了这个选项，<span class="code">^</span>和<span class="code">$</span>的意义就变成了<span class="desc">匹配行的开始处和结束处</span>。</p>
<h2 id="escape">
字符转义</h2>
<p>
如果你想查找元字符本身的话，比如你查找<span class="desc">.</span>,或者<span class="desc">*</span>,就出现了问题：你没法指定它们，因为它们会被解释成其它的意思。这时你就必须使用<span class="code">\</span>来取消这些字符的特殊意义。因此，你应该使用<span class="regex">\.</span>和<span class="regex">\*</span>。当然，要查找<span class="desc">\</span>本身，你也得用<span class="regex">\\</span>.</p>
<p>
例如：<span class="regex">www\.unibetter\.com</span>匹配<span class="desc">www.unibetter.com</span>，<span class="regex">c:\\Windows</span>匹配<span class="desc">c:\Windows</span>。</p>
<h2 id="repeat">
重复</h2>
<p>
你已经看过了前面的<span class="code">*</span>,<span class="code">+</span>,<span class="code">{2}</span>,<span class="code">{5,12}</span>这几个匹配重复的方式了。下面是正则表达式中所有的限定符(指定数量的代码，例如*,{5,12}等)：</p>
<table cellspacing="0">
    <caption>
    表2.常用的限定符</caption>
    <tbody>
        <tr>
            <th>
            代码/语法</th>
            <th>
            说明</th>
        </tr>
        <tr>
            <td>
            <span class="code">*</span></td>
            <td>
            <span class="desc">重复零次或更多次</span></td>
        </tr>
        <tr>
            <td>
            <span class="code">+</span></td>
            <td>
            <span class="desc">重复一次或更多次</span></td>
        </tr>
        <tr>
            <td>
            <span class="code">?</span></td>
            <td>
            <span class="desc">重复零次或一次</span></td>
        </tr>
        <tr>
            <td>
            <span class="code">{n}</span></td>
            <td>
            <span class="desc">重复n次</span></td>
        </tr>
        <tr>
            <td>
            <span class="code">{n,}</span></td>
            <td>
            <span class="desc">重复n次或更多次</span></td>
        </tr>
        <tr>
            <td>
            <span class="code">{n,m}</span></td>
            <td>
            <span class="desc">重复n到m次</span></td>
        </tr>
    </tbody>
</table>
<p>
下面是一些使用重复的例子：</p>
<p>
<span class="regex">Windows\d+</span>匹配<span class="desc">Windows后面跟1个或更多数字</span></p>
<p>
<span class="regex">13\d{9}</span>匹配<span class="desc">13后面跟9个数字(中国的手机号)</span></p>
<p>
<span class="regex">^\w+</span>匹配<span class="desc">一行的第一个单词(或整个字符串的第一个单词，具体匹配哪个意思得看选项设置)</span></p>
<h2 id="charclass">
字符类</h2>
<p>
要想查找数字，字母或数字，空白是很简单的，因为已经有了对应这些字符集合的元字符，但是如果你想匹配没有预定义元字符的字符集合(比如元音字母a,e,i,o,u),应该怎么办？</p>
<p>
很简单，你只需要在中括号里列出它们就行了，像<span class="regex">[aeiou]</span>就匹配<span class="desc">任何一个英文元音字母</span>，<span class="regex">[.?!]</span>匹配<span class="desc">标点符号(.或?或!)</span>(英文语句通常只以这三个标点结束)。</p>
<p>
我们也可以轻松地指定一个字符<span class="name">范围</span>，像<span class="regex">[0-9]</span>代表的含意与<span class="regex">\d</span>就是完全一致的：<span class="desc">一位数字</span>，同理<span class="regex">[a-z0-9A-Z_]</span>也完全等同于<span class="code">\w</span>（如果只考虑英文的话）。</p>
<p>
下面是一个更复杂的表达式：<span class="regex">\(?0\d{2}[) -]?\d{8}</span>。</p>
<p>
这个表达式可以匹配<span class="desc">几种格式的电话号码</span>，像<span class="string">(010)88886666</span>，或<span class="string">022-22334455</span>，或<span class="string">02912345678</span>等。我们对它进行一些分析吧：首先是一个转义字符<span class="part">\(</span>,它能出现0次或1次(<span class="part">?</span>),然后是一个<span class="part">0</span>，后面跟着2个数字(<span class="part">\d{2}</span>)，然后是<span class="part">)</span>或<span class="part">-</span>或<span class="part">空格</span>中的一个，它出现1次或不出现(<span class="part">?</span>)，最后是8个数字(<span class="part">\d{8}</span>)。不幸的是，它也能匹配<span class="string">010)12345678</span>或<span class="string">(022-87654321</span>这样的&#8220;不正确&#8221;的格式。要解决这个问题，请在本教程的下面查找答案。</p>
<h2 id="negation">
反义</h2>
<p>
有时需要查找不属于某个能简单定义的字符类的字符。比如想查找除了数字以外，其它任意字符都行的情况，这时需要用到<span class="name">反义</span>：</p>
<table cellspacing="0">
    <caption>
    表3.常用的反义代码</caption>
    <tbody>
        <tr>
            <th>
            代码/语法</th>
            <th>
            说明</th>
        </tr>
        <tr>
            <td>
            <span class="code">\W</span></td>
            <td>
            <span class="desc">匹配任意不是字母，数字，下划线，汉字的字符</span></td>
        </tr>
        <tr>
            <td>
            <span class="code">\S</span></td>
            <td>
            <span class="desc">匹配任意不是空白符的字符</span></td>
        </tr>
        <tr>
            <td>
            <span class="code">\D</span></td>
            <td>
            <span class="desc">匹配任意非数字的字符</span></td>
        </tr>
        <tr>
            <td>
            <span class="code">\B</span></td>
            <td>
            <span class="desc">匹配不是单词开头或结束的位置</span></td>
        </tr>
        <tr>
            <td>
            <span class="code">[^x]</span></td>
            <td>
            <span class="desc">匹配除了x以外的任意字符</span></td>
        </tr>
        <tr>
            <td>
            <span class="code">[^aeiou]</span></td>
            <td>
            <span class="desc">匹配除了aeiou这几个字母以外的任意字符</span></td>
        </tr>
    </tbody>
</table>
<p>
例子：<span class="regex">\S+</span>匹配<span class="desc">不包含空白符的字符串</span>。</p>
<p>
<span class="regex">&lt;a[^&gt;]+&gt;</span>匹配<span class="desc">用尖括号括起来的以a开头的字符串</span>。</p>
<h2 id="alternative">
替换</h2>
<p>
好了，现在终于到了解决3位或4位区号问题的时间了。正则表达式里的<span class="name">替换</span>指的是有几种规则，如果满足其中任意一种规则都应该当成匹配，具体方法是用<span class="code">|</span>把不同的规则分隔开。听不明白？没关系，看例子：</p>
<p>
<span class="regex">0\d{2}-\d{8}|0\d{3}-\d{7}</span>这个表达式能<span class="desc">匹配两种以连字号分隔的电话号码：一种是三位区号，8位本地号(如010-12345678)，一种是4位区号，7位本地号(0376-2233445)</span>。</p>
<p>
<span class="regex">\(0\d{2}\)[- ]?\d{8}|0\d{2}[- ]?\d{8}</span>这个表达式<span class="desc">匹配3位区号的电话号码，其中区号可以用小括号括起来，也可以不用，区号与本地号间可以用连字号或空格间隔，也可以没有间隔</span>。你可以试试用替换|把这个表达式扩展成也支持4位区号的。</p>
<p>
<span class="regex">\d{5}-\d{4}|\d{5}</span>这个表达式用于匹配美国的邮政编码。美国邮编的规则是5位数字，或者用连字号间隔的9位数字。之所以要给出这个例子是因为它能说明一个问题：<strong>使用替换时，顺序是很重要的</strong>。如果你把它改成<span class="regex">\d{5}|\d{5}-\d{4}</span>的话，那么就只会匹配5位的邮编(以及9位邮编的前5位)。原因是匹配替换时，将会从左到右地测试每个分枝条件，如果满足了某个分枝的话，就不会去管其它的替换条件了。</p>
<p>
<span class="regex">Windows98|Windows2000|WindosXP</span>这个例子是为了告诉你替换不仅仅能用于两种规则，也能用于更多种规则。</p>
<h2 id="grouping">
分组</h2>
<p>
我们已经提到了怎么重复单个字符（直接在字符后面加上限定符就行了）；但如果想要重复多个字符又该怎么办？你可以用小括号来指定<span class="name">子表达式</span>(也叫做<span class="name">分组</span>)，然后你就可以指定这个子表达式的重复次数了，你也可以对子表达式进行其它一些操作(后面会有介绍)。</p>
<p>
<span class="regex">(\d{1,3}\.){3}\d{1,3}</span>是一个<span class="desc">简单的IP地址匹配</span>表达式。要理解这个表达式，请按下列顺序分析它：<span class="part">\d{1,3}</span>匹配<span class="desc">1到3位的数字</span>，<span class="part">(\d{1,3}\.){3}</span>匹配<span class="desc">三位数字加上一个英文句号(这个整体也就是这个<span class="name">分组</span>)重复3次</span>，最后再加上<span class="desc">一个一到三位的数字</span>(<span class="part">\d{1,3}</span>)。</p>
<p>
不幸的是，它也将匹配<span class="string">256.300.888.999</span>这
种不可能存在的IP地址(IP地址中每个数字都不能大于255。题外话，好像反恐24小时第三季的编剧不知道这一点，汗...)。如果能使用算术比较的
话，或许能简单地解决这个问题，但是正则表达式中并不提供关于数学的任何功能，所以只能使用冗长的分组，选择，字符类来描述一个正确的IP地址：<span class="regex">((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)</span>。</p>
<p>
理解这个表达式的关键是理解<span class="part">2[0-4]\d|25[0-5]|[01]?\d\d?</span>，这里我就不细说了，你自己应该能分析得出来它的意义。</p>
<h2 id="backreference">
后向引用</h2>
<p>
使用小括号指定一个子表达式后，<strong>匹配这个子表达式的文本</strong>(也就是此分组捕获的内容)可以在表达式或其它程序中作进一步的处理。默认情况下，每个分组会自动拥有一个<span class="name">组号</span>，规则是：从左向右，以分组的左括号为标志，第一个出现的分组的组号为1，第二个为2，以此类推。</p>
<p>
<span class="name">后向引用</span>用于重复搜索前面某个分组匹配的文本。例如，<span class="part">\1</span>代表<span class="desc">分组1匹配的文本</span>。难以理解？请看示例：</p>
<p>
<span class="regex">\b(\w+)\b\s+\1\b</span>可以用来匹配<span class="desc">重复的单词</span>，像<span class="string">go go</span>, <span class="string">kitty kitty</span>。首先是<span class="desc">一个单词</span>，也就是<span class="desc">单词开始处和结束处之间的多于一个的字母或数字</span>(<span class="part">\b(\w+)\b</span>)，然后是<span class="desc">1个或几个空白符</span>(<span class="part">\s+</span>)，最后是<span class="desc">前面匹配的那个单词</span>(<span class="part">\1</span>)。</p>
<p>
你也可以自己指定子表达式的<span class="name">组名</span>。要指定一个子表达式的组名，请使用这样的语法：<span class="code">(?&lt;Word&gt;\w+)</span>(或者把尖括号换成<span class="code">'</span>也行：<span class="code">(?'Word'\w+)</span>),这样就把<span class="part">\w+</span>的组名指定为<span class="part">Word</span>了。要反向引用这个分组<span class="name">捕获</span>的内容，你可以使用<span class="code">\k&lt;Word&gt;</span>,所以上一个例子也可以写成这样：<span class="regex">\b(?&lt;Word&gt;\w+)\b\s+\k&lt;Word&gt;\b</span>。</p>
<p>
使用小括号的时候，还有很多特定用途的语法。下面列出了最常用的一些：</p>
<table cellspacing="0">
    <caption>
    表4.分组语法</caption>
    <tbody>
        <tr>
            <th colspan="2">
            捕获</th>
        </tr>
        <tr>
            <td>
            <span class="code">(exp)</span></td>
            <td>
            <span class="desc">匹配exp,并捕获文本到自动命名的组里</span></td>
        </tr>
        <tr>
            <td>
            <span class="code">(?&lt;name&gt;exp)</span></td>
            <td>
            <span class="desc">匹配exp,并捕获文本到名称为name的组里，也可以写成(?'name'exp)</span></td>
        </tr>
        <tr>
            <td>
            <span class="code">(?:exp)</span></td>
            <td>
            <span class="desc">匹配exp,不捕获匹配的文本，也不给此分组分配组号</span></td>
        </tr>
        <tr>
            <th colspan="2">
            零宽断言</th>
        </tr>
        <tr>
            <td>
            <span class="code">(?=exp)</span></td>
            <td>
            <span class="desc">匹配exp前面的位置</span></td>
        </tr>
        <tr>
            <td>
            <span class="code">(?&lt;=exp)</span></td>
            <td>
            <span class="desc">匹配exp后面的位置</span></td>
        </tr>
        <tr>
            <td>
            <span class="code">(?!exp)</span></td>
            <td>
            <span class="desc">匹配后面跟的不是exp的位置</span></td>
        </tr>
        <tr>
            <td>
            <span class="code">(?&lt;!exp)</span></td>
            <td>
            <span class="desc">匹配前面不是exp的位置</span></td>
        </tr>
        <tr>
            <th colspan="2">
            注释</th>
        </tr>
        <tr>
            <td>
            <span class="code">(?#comment)</span></td>
            <td>
            <span class="desc">这种类型的组不对正则表达式的处理产生任何影响，用于提供注释让人阅读</span></td>
        </tr>
    </tbody>
</table>
<p>
我们已经讨论了前两种语法。第三个<span class="code">(?:exp)</span>不会改变正则表达式的处理方式，只是这样的组匹配的内容<span class="desc">不会像前两种那样被捕获到某个组里面</span>。</p>
<h2 id="lookaround">
零宽断言</h2>
<p>
接下来的四个用于查找在某些内容(但并不包括这些内容)之前或之后的东西，也就是说它们像<span class="code">\b</span>,<span class="code">^</span>,<span class="code">$</span>那样用于指定一个位置，这个位置应该满足一定的条件(<a href="http://www.unibetter.com/deerchao/zhengzhe-biaodashi-jiaocheng-se.htm#reference">断言</a>)，因此它们也被称为<span class="name">零宽断言</span>。最好还是拿例子来说明吧：</p>
<p>
<span class="code">(?=exp)</span>也叫<span class="name">零宽度正预测先行断言</span>，它<span class="desc">断言自身出现的位置的后面能匹配表达式exp</span>。比如<span class="regex">\b\w+(?=ing\b)</span>，匹配<span class="desc">以ing结尾的单词的前面部分(除了ing以外的部分)</span>，如查找<span class="string">I'm singing while you're dancing.</span>时，它会匹配<span class="desc">sing</span>和<span class="desc">danc</span>。</p>
<p>
<span class="code">(?&lt;=exp)</span>也叫<span class="name">零宽度正回顾后发断言</span>，它<span class="desc">断言自身出现的位置的前面能匹配表达式exp</span>。比如<span class="regex">(?&lt;=\bre)\w+\b</span>会匹配<span class="desc">以re开头的单词的后半部分(除了re以外的部分)</span>，例如在查找<span class="string">reading a book</span>时，它匹配<span class="desc">ading</span>。</p>
<p>
假如你想要给一个很长的数字中每三位间加一个逗号(当然是从右边加起了)，你可以这样查找需要在前面和里面添加逗号的部分：<span class="regex">((?&lt;=\d)\d{3})*\b</span>，用它对<span class="string">1234567890</span>进行查找时结果是<span class="desc">234567890</span>。</p>
<p>
下面这个例子同时使用了这两种断言：<span class="regex">(?&lt;=\s)\d+(?=\s)</span>匹配<span class="desc">以空白符间隔的数字(再次强调，不包括这些空白符)</span>。</p>
<h2 id="negativelookaround">
负向零宽断言</h2>
<p>
前面我们提到过怎么查找<strong>不是某个字符或不在某个字符类里</strong>的字符的方法(反义)。但是如果我们只是想要<strong>确保某个字符没有出现，但并不想去匹配它</strong>时怎么办？例如，如果我们想查找这样的单词--它里面出现了字母q,但是q后面跟的不是字母u,我们可以尝试这样：</p>
<p>
<span class="regex">\b\w*q[^u]\w*\b</span>匹配<span class="desc">包含<strong>后面不是字母u的字母q</strong>的单词</span>。但是如果多做测试(或者你思维足够敏锐，直接就观察出来了)，你会发现，如果q出现在单词的结尾的话，像<strong>Iraq</strong>,<strong>Benq</strong>，这个表达式就会出错。这是因为<span class="part">[^u]</span>总要匹配一个字符，所以如果q是单词的最后一个字符的话，后面的<span class="part">[^u]</span>将会匹配q后面的单词分隔符(可能是空格，或者是句号或其它的什么)，后面的<span class="part">\w*\b</span>将会匹配下一个单词，于是<span class="regex">\b\w*q[^u]\w*\b</span>就能匹配整个<span class="string">Iraq fighting</span>。<span class="name">负向零宽断言</span>能解决这样的问题，因为它只匹配一个位置，并不<strong>消费</strong>任何字符。现在，我们可以这样来解决这个问题：<span class="regex">\b\w*q(?!u)\w*\b</span>。</p>
<p>
<span class="name">零宽度负预测先行断言</span><span class="code">(?!exp)</span>，<span class="desc">断言此位置的后面不能匹配表达式exp</span>。例如：<span class="regex">\d{3}(?!\d)</span>匹配<span class="desc">三位数字，而且这三位数字的后面不能是数字</span>；<span class="regex">\b((?!abc)\w)+\b</span>匹配<span class="desc">不包含连续字符串abc的单词</span>。</p>
<p>
同理，我们可以用<span class="code">(?&lt;!exp)</span>,<span class="name">零宽度正回顾后发断言</span>来<span class="desc">断言此位置的前面不能匹配表达式exp</span>：<span class="regex">(?&lt;![a-z])\d{7}</span>匹配<span class="desc">前面不是小写字母的七位数字</span>。</p>
<p>
一个更复杂的例子：<span class="regex">(?&lt;=&lt;(\w+)&gt;).*(?=&lt;\/\1&gt;)</span>匹配<span class="desc">不包含属性的简单HTML标签内里的内容</span>。<span class="code">(&lt;?(\w+)&gt;)</span>指定了这样的<span class="name">前缀</span>：<span class="desc">被尖括号括起来的单词</span>(比如可能是&lt;b&gt;)，然后是<span class="part">.*</span>(任意的字符串),最后是一个<span class="name">后缀</span><span class="part">(?=&lt;\/\1&gt;)</span>。注意后缀里的<span class="part">\/</span>，它用到了前面提过的字符转义；<span class="part">\1</span>则是一个反向引用，引用的正是<span class="desc">捕获的第一组</span>，前面的<span class="part">(\w+)</span>匹配的内容，这样如果前缀实际上是&lt;b&gt;的话，后缀就是&lt;/b&gt;了。整个表达式匹配的是&lt;b&gt;和&lt;/b&gt;之间的内容(再次提醒，不包括前缀和后缀本身)。</p>
<h2 id="commenting">
注释</h2>
<p>
小括号的另一种用途是通过语法<span class="code">(?#comment)</span>来包含注释。例如：<span class="regex">2[0-4]\d(?#200-249)|25[0-5](?#250-255)|[01]?\d\d?(?#0-199)</span>。</p>
<p>
要包含注释的话，最好是启用&#8220;忽略模式里的空白符&#8221;选项，这样在编写表达式时能任意的添加空格，Tab，换行，而实际使用时这些都将被忽略。启用这个选项后，在#后面到这一行结束的所有文本都将被当成注释忽略掉。</p>
<p>
例如，我们可以前面的一个表达式写成这样：</p>
<pre class="regex">      (?&lt;=    # 断言要匹配的文本的前缀<br />
&lt;(\w+)&gt; # 查找尖括号括起来的字母或数字(即HTML/XML标签)<br />
)       # 前缀结束<br />
.*      # 匹配任意文本<br />
(?=     # 断言要匹配的文本的后缀<br />
&lt;\/\1&gt;  # 查找尖括号括起来的内容：前面是一个"/"，后面是先前捕获的标签<br />
)       # 后缀结束<br />
</pre>
<h2 id="greedyandlazy">
贪婪与懒惰</h2>
<p>
当正则表达式中包含能接受重复的限定符时，通常的行为是（在使整个表达式能得到匹配的前提下）匹配<strong>尽可能多</strong>的字符。考虑这个表达式：<span class="regex">a.*b</span>，它将会匹配<span class="desc">最长的以a开始，以b结束的字符串</span>。如果用它来搜索<span class="string">aabab</span>的话，它会匹配整个字符串<span class="desc">aabab</span>。这被称为<span class="name">贪婪</span>匹配。</p>
<p dragover="true">
有时，我们更需要<span class="name">懒惰</span>匹配，也就是匹配<strong>尽可能少</strong>的字符。前面给出的限定符都可以被转化为懒惰匹配模式，只要在它后面加上一个问号<span class="code">?</span>。这样<span class="regex">.*?</span>就意味着<span class="desc">匹配任意数量的重复，但是在能使整个匹配成功的前提下使用最少的重复</span>。现在看看懒惰版的例子吧：</p>
<p dragover="true">
<span class="regex">a.*?b</span>匹配<span class="desc">最短的，以a开始，以b结束的字符串</span>。如果把它应用于<span dragover="true" class="string">aabab</span>的话，它会匹配<span class="desc">aab</span>和<span class="desc">ab</span>（为什么第一个匹配是aab而不是ab？简单地说，因为正则表达式有另一条规则，比懒惰／贪婪规则的优先级更高：最先开始的匹配拥有最高的优先权——The Match That Begins Earliest Wins）。</p>
<table cellspacing="0">
    <caption>
    表5.懒惰限定符</caption>
    <tbody>
        <tr>
            <td>
            <span class="code">*?</span></td>
            <td dragover="true">
            <span class="desc">重复任意次，但尽可能少重复</span></td>
        </tr>
        <tr>
            <td>
            <span class="code">+?</span></td>
            <td>
            <span dragover="true" class="desc">重复1次或更多次，但尽可能少重复</span></td>
        </tr>
        <tr>
            <td>
            <span class="code">??</span></td>
            <td>
            <span dragover="true" class="desc">重复0次或1次，但尽可能少重复</span></td>
        </tr>
        <tr>
            <td>
            <span class="code">{n,m}?</span></td>
            <td>
            <span class="desc">重复n到m次，但尽可能少重复</span></td>
        </tr>
        <tr>
            <td>
            <span class="code">{n,}?</span></td>
            <td>
            <span class="desc">重复n次以上，但尽可能少重复</span></td>
        </tr>
    </tbody>
</table>
<h2 id="regexoptions">处理选项</h2>
<p>上面介绍了几个选项如忽略大小写，处理多行等，这些选项能用来改变处理正则表达式的方式。下面是.Net中常用的正则表达式选项：</p>
<table cellspacing="0">
    <caption>表6.常用的处理选项</caption>
    <thead>
        <tr>
            <th>名称</th>
            <th>说明</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>IgnoreCase(忽略大小写)</td>
            <td>匹配时不区分大小写。</td>
        </tr>
        <tr>
            <td>Multiline(多行模式)</td>
            <td>更改<span class="code">^</span>和<span class="code">$</span>的含义，使它们分别在任意一行的行首和行尾匹配，而不仅仅在整个字符串的开头和结尾匹配。(在此模式下,<span class="code">$</span>的精确含意是:匹配\n之前的位置以及字符串结束前的位置.) </td>
        </tr>
        <tr>
            <td>Singleline(单行模式)</td>
            <td>更改<span class="code">.</span>的含义，使它与每一个字符匹配（包括换行符\n）。 </td>
        </tr>
        <tr>
            <td>IgnorePatternWhitespace(忽略空白)</td>
            <td>忽略表达式中的非转义空白并启用由<span class="code">#</span>标记的注释。</td>
        </tr>
        <tr>
            <td>RightToLeft(从右向左查找)</td>
            <td>匹配从右向左而不是从左向右进行。</td>
        </tr>
        <tr>
            <td>ExplicitCapture(显式捕获)</td>
            <td>仅捕获已被显式命名的组。</td>
        </tr>
        <tr>
            <td>ECMAScript(JavaScript兼容模式)</td>
            <td>使表达式的行为与它在JavaScript里的行为一致。</td>
        </tr>
    </tbody>
</table>
<p>一个经常被问到的问题是：是不是只能同时使用多行模式和单行模式中的一种？答案是：不是。这两个选项之间没有任何关系，除了它们的名字比较相似（以至于让人感到疑惑）以外。</p>
<h2 id="balancedgroup">
平衡组/递归匹配</h2>
<p class="important">
注意：这里介绍的平衡组语法是由.Net Framework支持的；其它语言／库不一定支持这种功能，或者支持此功能但需要使用不同的语法。
</p>
<p>
有时我们需要匹配像<span class="desc">( 100 * ( 50 + 15 ) )这样的可嵌套的层次性结构</span>，这时简单地使用<span class="code">\(.+\)</span>则只会匹配到最左边的左括号和最右边的右括号之间的内容(这里我们讨论的是贪婪模式，懒惰模式也有下面的问题)。假如原来的字符串里的左括号和右括号出现的次数不相等，比如<span class="string">( 5 / ( 3 + 2 ) ) )</span>，那我们的匹配结果里两者的个数也不会相等。有没有办法在这样的字符串里匹配到最长的，配对的括号之间的内容呢？
</p>
<p>
为了避免<span class="code">(</span>和<span class="code">\(</span>把你的大脑彻底搞糊涂，我们还是用尖括号代替圆括号吧。现在我们的问题变成了如何把<span class="string">xx &lt;aa &lt;bbb&gt; &lt;bbb&gt; aa&gt; yy</span>这样的字符串里，最长的配对的尖括号内的内容捕获出来？
</p>
<p>
这里需要用到以下的语法构造：</p>
<ul>
    <li><span class="code">(?'group')</span> 把捕获的内容命名为group,并压入堆栈</li>
    <li><span class="code">(?'-group')</span> 从堆栈上弹出最后压入堆栈的名为group的捕获内容，如果堆栈本来为空，则本分组的匹配失败</li>
    <li><span class="code">(?(group)yes|no)</span> 如果堆栈上存在以名为group的捕获内容的话，继续匹配yes部分的表达式，否则继续匹配no部分</li>
    <li><span class="code">(?!)</span> 零宽负向先行断言，由于没有后缀表达式，试图匹配总是失败</li>
</ul>
<p>
如果你不是一个程序员（或者你是一个对堆栈的概念不熟的程序员），你就这样理解上面的三种语法吧：第一个就是在黑板上写一个
"group"，第二个就是从黑板上擦掉一个"group"，第三个就是看黑板上写的还有没有"group"，如果有就继续匹配yes部分，否则就匹配
no部分。</p>
<p>
我们需要做的是每碰到了左括号，就在黑板上写一个"group"，每碰到一个右括号，就擦掉一个，到了最后就看看黑板上还有没有－－如果有那就证明左括号比右括号多，那匹配就应该失败。
</p>
<pre class="regex">&lt;                         #最外层的左括号<br />
[^&lt;&gt;]*                #最外层的左括号后面的不是括号的内容<br />
(<br />
(<br />
(?'Open'&lt;)    #碰到了左括号，在黑板上写一个"Open"<br />
[^&lt;&gt;]*       #匹配左括号后面的不是括号的内容<br />
)+<br />
(<br />
(?'-Open'&gt;)   #碰到了右括号，擦掉一个"Open"<br />
[^&lt;&gt;]*        #匹配右括号后面不是括号的内容<br />
)+<br />
)*<br />
(?(Open)(?!))         #在遇到最外层的右括号前面，判断黑板上还有没有没擦掉的"Open"；如果还有，则匹配失败<br />
&gt;                         #最外层的右括号</pre>
<p>
平衡组的一个最常见的应用就是匹配HTML,下面这个例子可以匹配<span class="desc">嵌套的&lt;div&gt;标签</span>：<span class="regex">&lt;div[^&gt;]*&gt;[^&lt;&gt;]*(((?'Open'&lt;div[^&gt;]*&gt;)[^&lt;&gt;]*)+((?'-Open'&lt;/div&gt;)[^&lt;&gt;]*)+)*(?(Open)(?!))&lt;/div&gt;</span>.</p>
<h2 id="more">
还有些什么东西没提到</h2>
<p>
我已经描述了构造正则表达式的大量元素，还有一些我没有提到的东西。下面是未提到的元素的列表，包含语法和简单的说明。你可以在网上找到更详细的参考资料来学习它们--当你需要用到它们的时候。如果你安装了MSDN
Library,你也可以在里面找到关于.net下正则表达式详细的文档。</p>
<table cellspacing="0">
    <caption>
    表7.尚未详细讨论的语法</caption>
    <tbody>
        <tr>
            <td>
            <span class="code">\a</span></td>
            <td>
            <span class="desc">报警字符(打印它的效果是电脑嘀一声)</span></td>
        </tr>
        <tr>
            <td>
            <span class="code">\b</span></td>
            <td>
            <span class="desc">通常是单词分界位置，但如果在字符类里使用代表退格</span></td>
        </tr>
        <tr>
            <td>
            <span class="code">\t</span></td>
            <td>
            <span class="desc">制表符，Tab</span></td>
        </tr>
        <tr>
            <td>
            <span class="code">\r</span></td>
            <td>
            <span class="desc">回车</span></td>
        </tr>
        <tr>
            <td>
            <span class="code">\v</span></td>
            <td>
            <span class="desc">竖向制表符</span></td>
        </tr>
        <tr>
            <td>
            <span class="code">\f</span></td>
            <td>
            <span class="desc">换页符</span></td>
        </tr>
        <tr>
            <td>
            <span class="code">\n</span></td>
            <td>
            <span class="desc">换行符</span></td>
        </tr>
        <tr>
            <td>
            <span class="code">\e</span></td>
            <td>
            <span class="desc">Escape</span></td>
        </tr>
        <tr>
            <td>
            <span class="code">\0nn</span></td>
            <td>
            <span class="desc">ASCII代码中八进制代码为nn的字符</span></td>
        </tr>
        <tr>
            <td>
            <span class="code">\xnn</span></td>
            <td>
            <span class="desc">ASCII代码中十六进制代码为nn的字符</span></td>
        </tr>
        <tr>
            <td>
            <span class="code">\unnnn</span></td>
            <td>
            <span class="desc">Unicode代码中十六进制代码为nnnn的字符</span></td>
        </tr>
        <tr>
            <td>
            <span class="code">\cN</span></td>
            <td>
            <span class="desc">ASCII控制字符。比如\cC代表Ctrl+C</span></td>
        </tr>
        <tr>
            <td>
            <span class="code">\A</span></td>
            <td>
            <span class="desc">字符串开头(类似^，但不受处理多行选项的影响)</span></td>
        </tr>
        <tr>
            <td>
            <span class="code">\Z</span></td>
            <td>
            <span class="desc">字符串结尾或行尾(不受处理多行选项的影响)</span></td>
        </tr>
        <tr>
            <td>
            <span class="code">\z</span></td>
            <td>
            <span class="desc">字符串结尾(类似$，但不受处理多行选项的影响)</span></td>
        </tr>
        <tr>
            <td>
            <span class="code">\G</span></td>
            <td>
            <span class="desc">当前搜索的开头</span></td>
        </tr>
        <tr>
            <td>
            <span class="code">\p{name}</span></td>
            <td>
            <span class="desc">Unicode中命名为name的字符类，例如\p{IsGreek}</span></td>
        </tr>
        <tr>
            <td>
            <span class="code">(?&gt;exp)</span></td>
            <td>
            <span class="desc">贪婪子表达式</span></td>
        </tr>
        <tr>
            <td>
            <span class="code">(?&lt;x&gt;-&lt;y&gt;exp)</span></td>
            <td>
            <span class="desc">平衡组</span></td>
        </tr>
        <tr>
            <td>
            <span class="code">(?im-nsx:exp)</span></td>
            <td>
            <span class="desc">在子表达式exp中改变处理选项</span></td>
        </tr>
        <tr>
            <td>
            <span class="code">(?im-nsx)</span></td>
            <td>
            <span class="desc">为表达式后面的部分改变处理选项</span></td>
        </tr>
        <tr>
            <td>
            <span class="code">(?(exp)yes|no)</span></td>
            <td>
            <span class="desc">把exp当作零宽正向先行断言，如果在这个位置能匹配，使用yes作为此组的表达式；否则使用no</span></td>
        </tr>
        <tr>
            <td>
            <span class="code">(?(exp)yes)</span></td>
            <td>
            <span class="desc">同上，只是使用空表达式作为no</span></td>
        </tr>
        <tr>
            <td>
            <span class="code">(?(name)yes|no)</span></td>
            <td>
            <span class="desc">如果命名为name的组捕获到了内容，使用yes作为表达式；否则使用no</span></td>
        </tr>
        <tr>
            <td>
            <span class="code">(?(name)yes)</span></td>
            <td>
            <span class="desc">同上，只是使用空表达式作为no</span></td>
        </tr>
    </tbody>
</table>
<h2 id="contact">联系作者</h2>
<p>好吧,我承认,我骗了你,读到这里你肯定花了不止30分钟.相信我,这是我的错,而不是因为你太笨.我之所以说"30分钟",是为了让你有信心,有耐心继续下去.既然你看到了这里,那证明我的阴谋成功了.上这种当的滋味还不错吧?</p>
<p>要投诉我,或者觉得我其实可以做得更好,或者有任何其它问题,欢迎来<a href="http://www.cnblogs.com/deerchao/archive/2006/08/24/zhengzhe30fengzhongjiaocheng.html">我的博客</a>进行讨论.</p>
<br />
<h2 id="reference">
一些我认为你可能已经知道的术语的参考</h2>
<dl><dt>字符</dt><dd>程序处理文字时最基本的单位，可能是字母，数字，标点符号，空格，换行符，汉字等等。</dd><dt>字符串</dt><dd>0个或更多个字符的序列。</dd><dt>文本</dt><dd>文字，字符串。</dd><dt>匹配</dt><dd>符合规则，检验是否符合规则，符合规则的部分。</dd><dt>断言</dt><dd>声明一个应该为真的事实。只有当断言为真时才会对正则表达式继续进行匹配。</dd></dl>
<h2 id="resources">
网上的资源及本文参考文献</h2>
<ul>
    <li><a href="http://msdn.microsoft.com/library/chs/default.asp?url=/library/CHS/jscript7/html/jsreconintroductiontoregularexpressions.asp">
    微软的正则表达式教程</a></li>
    <li><a href="http://msdn2.microsoft.com/zh-cn/library/system.text.regularexpressions.regex.aspx">System.Text.RegularExpressions.Regex类(MSDN)</a></li>
    <li><a href="http://www.regular-expressions.info/">专业的正则表达式教学网站(英文)</a></li>
    <li><a href="http://weblogs.asp.net/whaggard/archive/2005/02/20/377025.aspx">关于.Net下的平衡组的详细讨论（英文）</a></li>
    <li><a href="http://www.oreilly.com/catalog/regex2/">Mastering Regular Expressions (Second Edition)</a></li>
</ul>
<h2 id="updatelog">更新说明</h2>
<ol>
    <li>2006-3-27 第一版</li>
    <li>2006-10-12 第二版
    <ul>
        <li>修正了几个细节上的错误和不准确的地方</li>
        <li>增加了对处理中文时的一些说明</li>
        <li>更改了几个术语的翻译（采用了MSDN的翻译方式）</li>
        <li>增加了平衡组的介绍</li>
        <li>放弃了对The Regulator的介绍，改用Regex Tester</li>
    </ul>
    </li>
    <li>2007-3-12 V2.1
    <ul>
        <li>修正了几个小的错误</li>
        <li>增加了对处理选项(RegexOptions)的介绍</li>
    </ul>
    </li>
    <li>2007-5-28 V2.2
    <ul>
        <li>重新组织了对零宽断言的介绍</li>
        <li>删除了几个不太合适的示例，添加了几个实用的示例</li>
        <li>其它一些微小的更改</li>
    </ul>
    </li>
    <li>2007-8-3 V2.21
    <ul>
        <li>修改了几处文字错误</li>
        <li>修改/添加了对$,\b的精确说明</li>
        <li>承认了作者是个骗子</li>
        <li>给RegexTester添加了Singleline选项的相关功能</li>
    </ul>
    </li>
</ol>
<img src ="http://www.blogjava.net/pts/aggbug/191353.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/pts/" target="_blank">pts</a> 2008-04-07 20:11 <a href="http://www.blogjava.net/pts/archive/2008/04/07/191353.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>