﻿<?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>C++博客-金庆的专栏-随笔分类-6. Python</title><link>http://www.cppblog.com/jinq0123/category/5138.html</link><description /><language>zh-cn</language><lastBuildDate>Wed, 21 Nov 2018 04:18:53 GMT</lastBuildDate><pubDate>Wed, 21 Nov 2018 04:18:53 GMT</pubDate><ttl>60</ttl><item><title>vs2017 linux 编译输出改成 vs 格式</title><link>http://www.cppblog.com/jinq0123/archive/2018/11/21/216073.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Wed, 21 Nov 2018 02:57:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2018/11/21/216073.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/216073.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2018/11/21/216073.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/216073.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/216073.html</trackback:ping><description><![CDATA[<div>vs2017 linux 编译输出改成 vs 格式</div><div></div><div><div>(金庆的专栏 2018.11)</div></div><div></div><div><div style="background-color:#eeeeee;font-size:13px;border:1px solid #CCCCCC;padding-right: 5px;padding-bottom: 4px;padding-left: 4px;padding-top: 4px;width: 98%;word-break:break-all"><!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />--><span style="color: #008080; ">&nbsp;1</span>&nbsp;<span style="color: #008000; ">#</span><span style="color: #008000; ">!/usr/bin/python&nbsp;</span><span style="color: #008000; "><br /></span><span style="color: #008080; ">&nbsp;2</span>&nbsp;<span style="color: #008000; ">#</span><span style="color: #008000; ">&nbsp;-*-&nbsp;coding:&nbsp;utf-8&nbsp;-*-&nbsp;&nbsp;</span><span style="color: #008000; "><br /></span><span style="color: #008080; ">&nbsp;3</span>&nbsp;<span style="color: #008000; "></span><span style="color: #000000; "><br /></span><span style="color: #008080; ">&nbsp;4</span>&nbsp;<span style="color: #000000; "></span><span style="color: #800000; ">'''</span><span style="color: #800000; "><br /></span><span style="color: #008080; ">&nbsp;5</span>&nbsp;<span style="color: #800000; ">gcc2vs.py<br /></span><span style="color: #008080; ">&nbsp;6</span>&nbsp;<span style="color: #800000; "><br /></span><span style="color: #008080; ">&nbsp;7</span>&nbsp;<span style="color: #800000; ">功能：<br /></span><span style="color: #008080; ">&nbsp;8</span>&nbsp;<span style="color: #800000; ">将剪切板中gcc的编译输出格式转成vs格式，用于vs跳转到错误行。<br /></span><span style="color: #008080; ">&nbsp;9</span>&nbsp;<span style="color: #800000; ">vs2017&nbsp;linux&nbsp;编译输出为&nbsp;gcc&nbsp;格式，无法点击跳转，如：<br /></span><span style="color: #008080; ">10</span>&nbsp;<span style="color: #800000; ">/var/tmp/src/db<img src="http://www.cppblog.com/Images/dot.gif"  alt="" />e/Linux-Debug/Src/Team.cpp:16:1:&nbsp;错误：&#8216;x&#8217;不是一个类型名<br /></span><span style="color: #008080; ">11</span>&nbsp;<span style="color: #800000; ">须转为vs格式,&nbsp;如<br /></span><span style="color: #008080; ">12</span>&nbsp;<span style="color: #800000; ">/var/tmp/src/db<img src="http://www.cppblog.com/Images/dot.gif"  alt="" />e/Linux-Debug/Src/Team.cpp(16):1:&nbsp;错误：&#8216;x&#8217;不是一个类型名<br /></span><span style="color: #008080; ">13</span>&nbsp;<span style="color: #800000; "><br /></span><span style="color: #008080; ">14</span>&nbsp;<span style="color: #800000; ">如何使用：<br /></span><span style="color: #008080; ">15</span>&nbsp;<span style="color: #800000; "><br /></span><span style="color: #008080; ">16</span>&nbsp;<span style="color: #800000; ">首先须安装&nbsp;python,&nbsp;并安装&nbsp;pyperclip<br /></span><span style="color: #008080; ">17</span>&nbsp;<span style="color: #800000; ">pip&nbsp;install&nbsp;pyperclip<br /></span><span style="color: #008080; ">18</span>&nbsp;<span style="color: #800000; "><br /></span><span style="color: #008080; ">19</span>&nbsp;<span style="color: #800000; ">假设本文件为&nbsp;d:/tools/gcc2vs.py,<br /></span><span style="color: #008080; ">20</span>&nbsp;<span style="color: #800000; ">vs设置外部工具：工具-&gt;外部工具-&gt;添加<br /></span><span style="color: #008080; ">21</span>&nbsp;<span style="color: #800000; ">&nbsp;&nbsp;标题：gcc2vs(&amp;V)<br /></span><span style="color: #008080; ">22</span>&nbsp;<span style="color: #800000; ">&nbsp;&nbsp;命令：python.exe<br /></span><span style="color: #008080; ">23</span>&nbsp;<span style="color: #800000; ">&nbsp;&nbsp;参数：d:/tools/gcc2vs.py<br /></span><span style="color: #008080; ">24</span>&nbsp;<span style="color: #800000; ">&nbsp;&nbsp;选中"使用输出窗口"<br /></span><span style="color: #008080; ">25</span>&nbsp;<span style="color: #800000; "><br /></span><span style="color: #008080; ">26</span>&nbsp;<span style="color: #800000; ">参考：VS2010手动添加外部工具和快捷键&nbsp;&nbsp;<br /></span><span style="color: #008080; ">27</span>&nbsp;<span style="color: #800000; ">https://www.cnblogs.com/ChinaHook/p/4698733.html<br /></span><span style="color: #008080; ">28</span>&nbsp;<span style="color: #800000; "><br /></span><span style="color: #008080; ">29</span>&nbsp;<span style="color: #800000; ">当Linux构建输出后，点击输出窗口，ctrl-A&nbsp;选择全部，ctrl-C&nbsp;复制输出到剪切板，<br /></span><span style="color: #008080; ">30</span>&nbsp;<span style="color: #800000; ">然后&nbsp;alt-T,V&nbsp;运行添加的外部工具&nbsp;gcc2vs(&amp;V),&nbsp;更改输出格式，然后就可以点击错误跳转了。<br /></span><span style="color: #008080; ">31</span>&nbsp;<span style="color: #800000; "></span><span style="color: #800000; ">'''</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">32</span>&nbsp;<span style="color: #000000; "><br /></span><span style="color: #008080; ">33</span>&nbsp;<span style="color: #000000; "></span><span style="color: #0000FF; ">import</span><span style="color: #000000; ">&nbsp;re<br /></span><span style="color: #008080; ">34</span>&nbsp;<span style="color: #000000; "></span><span style="color: #0000FF; ">import</span><span style="color: #000000; ">&nbsp;pyperclip<br /></span><span style="color: #008080; ">35</span>&nbsp;<span style="color: #000000; "><br /></span><span style="color: #008080; ">36</span>&nbsp;<span style="color: #000000; "></span><span style="color: #008000; ">#</span><span style="color: #008000; ">&nbsp;待替换的格式</span><span style="color: #008000; "><br /></span><span style="color: #008080; ">37</span>&nbsp;<span style="color: #008000; "></span><span style="color: #000000; ">pattern&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;re.compile(r</span><span style="color: #800000; ">'</span><span style="color: #800000; ">/var/tmp/src/<img src="http://www.cppblog.com/Images/dot.gif"  alt="" /><img src="http://www.cppblog.com/Images/dot.gif"  alt="" />..-<img src="http://www.cppblog.com/Images/dot.gif"  alt="" />.-<img src="http://www.cppblog.com/Images/dot.gif"  alt="" />.-<img src="http://www.cppblog.com/Images/dot.gif"  alt="" />.-<img src="http://www.cppblog.com/Images/dot.gif"  alt="" /><img src="http://www.cppblog.com/Images/dot.gif"  alt="" /><img src="http://www.cppblog.com/Images/dot.gif"  alt="" /><img src="http://www.cppblog.com/Images/dot.gif"  alt="" />/Linux-Debug/(.*):([0-9]*):([0-9]*):&nbsp;</span><span style="color: #800000; ">'</span><span style="color: #000000; ">)<br /></span><span style="color: #008080; ">38</span>&nbsp;<span style="color: #000000; "><br /></span><span style="color: #008080; ">39</span>&nbsp;<span style="color: #000000; ">test_lines_src&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #800000; ">'''</span><span style="color: #800000; "><br /></span><span style="color: #008080; ">40</span>&nbsp;<span style="color: #800000; ">/var/tmp/src/db71a8ec-90bb-2838-98df-2dd35e71166e/Linux-Debug/003_servers/103_LobbyServer/Src/Team.cpp:16:1:&nbsp;错误：&#8216;x&#8217;不是一个类型名<br /></span><span style="color: #008080; ">41</span>&nbsp;<span style="color: #800000; ">生成失败。<br /></span><span style="color: #008080; ">42</span>&nbsp;<span style="color: #800000; "></span><span style="color: #800000; ">'''</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">43</span>&nbsp;<span style="color: #000000; ">test_lines_dst&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;</span><span style="color: #800000; ">'''</span><span style="color: #800000; "><br /></span><span style="color: #008080; ">44</span>&nbsp;<span style="color: #800000; ">003_servers/103_LobbyServer/Src/Team.cpp(16):1:&nbsp;错误：&#8216;x&#8217;不是一个类型名<br /></span><span style="color: #008080; ">45</span>&nbsp;<span style="color: #800000; ">生成失败。<br /></span><span style="color: #008080; ">46</span>&nbsp;<span style="color: #800000; "></span><span style="color: #800000; ">'''</span><span style="color: #000000; "><br /></span><span style="color: #008080; ">47</span>&nbsp;<span style="color: #000000; "></span><span style="color: #0000FF; ">assert</span><span style="color: #000000; ">&nbsp;test_lines_dst&nbsp;</span><span style="color: #000000; ">==</span><span style="color: #000000; ">&nbsp;re.sub(pattern,&nbsp;r</span><span style="color: #800000; ">'</span><span style="color: #800000; ">\1(\2):\3:&nbsp;</span><span style="color: #800000; ">'</span><span style="color: #000000; ">,&nbsp;test_lines_src)<br /></span><span style="color: #008080; ">48</span>&nbsp;<span style="color: #000000; "><br /></span><span style="color: #008080; ">49</span>&nbsp;<span style="color: #000000; "></span><span style="color: #008000; ">#</span><span style="color: #008000; ">&nbsp;剪切板中的gcc格式输出</span><span style="color: #008000; "><br /></span><span style="color: #008080; ">50</span>&nbsp;<span style="color: #008000; "></span><span style="color: #000000; ">src&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;pyperclip.paste()<br /></span><span style="color: #008080; ">51</span>&nbsp;<span style="color: #000000; "></span><span style="color: #008000; ">#</span><span style="color: #008000; ">&nbsp;转成vs格式</span><span style="color: #008000; "><br /></span><span style="color: #008080; ">52</span>&nbsp;<span style="color: #008000; "></span><span style="color: #000000; ">dst&nbsp;</span><span style="color: #000000; ">=</span><span style="color: #000000; ">&nbsp;re.sub(pattern,&nbsp;r</span><span style="color: #800000; ">'</span><span style="color: #800000; ">\1(\2):\3:&nbsp;</span><span style="color: #800000; ">'</span><span style="color: #000000; ">,&nbsp;src)<br /></span><span style="color: #008080; ">53</span>&nbsp;<span style="color: #000000; "></span><span style="color: #0000FF; ">print</span><span style="color: #000000; ">(dst)<br /></span><span style="color: #008080; ">54</span>&nbsp;<span style="color: #000000; "></span></div></div><img src ="http://www.cppblog.com/jinq0123/aggbug/216073.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2018-11-21 10:57 <a href="http://www.cppblog.com/jinq0123/archive/2018/11/21/216073.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>xlsx批量转为utf8的csv</title><link>http://www.cppblog.com/jinq0123/archive/2015/10/30/212153.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Fri, 30 Oct 2015 08:05:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2015/10/30/212153.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/212153.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2015/10/30/212153.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/212153.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/212153.html</trackback:ping><description><![CDATA[<div>xlsx批量转为utf8的csv<br /><br />(金庆的专栏)<br /><br />策划的配置表为 xlsx 表格，可以有注释，公式。<br />服务器和客户端使用的配置文件需要转成 csv 文件。<br />使用 WPS 另存无法批量转换，并且结果不是utf8编码的，还需要用Notepad++转编码。<br /><br />除了 xlsx 转为 csv, 其他格式文件保持原样，如 *.ini, *.xml, *.lua.<br />server/ 子目录特殊处理，不能复制到客户端。<br /><br />用python脚本实现，依赖 openpyxl 库。<br /><br /><span style="font-family:Courier New;color:#660000;">#!/usr/bin/env python<br /># coding: utf-8<br /># datatab.py<br /># 从策划配置表目录 game\Design\配置表\&#8221;<br />#&nbsp;&nbsp; 生成服务器的 game\Program\server\six\datatab\&#8221; 目录，<br />#&nbsp;&nbsp; 和客户端的 game\Program\client\Assets\Config\&#8221; 目录。<br />#&nbsp;&nbsp; 所有xlsx文件生成csv文件，其他文件原样复制。<br />#&nbsp;&nbsp; 其中 server\ 目录特殊处理，仅对服务器有效，客户端跳过。 <br />#<br /># 依赖openpyxl库：http://openpyxl.readthedocs.org/en/latest/<br /># 参考代码 http://segmentfault.com/q/1010000003006437?_ea=273128<br /># 测试环境：Python3.4<br /><br /># Usage: datatab.py &lt;game dir&gt;<br /># Example: datatab.py "d:\game"<br /># &lt;game dir&gt; 是根目录，包含Design/, Program/ 目录。<br /><br />from openpyxl import Workbook<br />from openpyxl.compat import range<br />from openpyxl.cell import get_column_letter<br />from openpyxl import load_workbook<br />import csv<br />import os<br />import sys<br />import shutil<br /><br />def xlsx2csv(filename):<br />&nbsp;&nbsp;&nbsp; # try:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xlsx_file_reader = load_workbook(filename = filename, data_only = True)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for sheet in xlsx_file_reader.get_sheet_names():<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # 仅第1个sheet输出到一个csv文件中，文件名后缀替换为.csv<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; csv_filename = os.path.splitext(filename)[0] + '.csv'<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; csv_file = open(csv_filename, 'w', encoding='utf8', newline='')<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; csv_file_writer = csv.writer(csv_file)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sheet_ranges = xlsx_file_reader[sheet]<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for row in sheet_ranges.rows:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; row_container = []<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for cell in row:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; row_container.append(cell.value)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; csv_file_writer.writerow(row_container)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # End of for row.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; csv_file.close()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break&nbsp; # 仅输出第1个sheet<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; # End of for sheet.<br />&nbsp;&nbsp;&nbsp; # End of try.<br />&nbsp;&nbsp;&nbsp; # except Exception as e:<br />&nbsp;&nbsp;&nbsp; #&nbsp;&nbsp;&nbsp; print(e)<br /># End of xlsx2csv().<br /><br />def datatab_convert(game_dir):<br />&nbsp;&nbsp;&nbsp; '''从 game\Design\配置表\ 输出到<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; game\Program\server\six\datatab\<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; game\Program\client\Assets\Config\<br />&nbsp;&nbsp;&nbsp; '''<br />&nbsp;&nbsp;&nbsp; design_dir = os.path.join(game_dir, 'Design/配置表/')<br />&nbsp;&nbsp;&nbsp; server_dir = os.path.join(game_dir, 'Program/server/six/datatab/')<br />&nbsp;&nbsp;&nbsp; client_dir = os.path.join(game_dir, 'Program/client/Assets/Config/')<br />&nbsp;&nbsp; &nbsp;<br />&nbsp;&nbsp;&nbsp; # 删除旧文件。<br />&nbsp;&nbsp;&nbsp; print("Delete " + server_dir)<br />&nbsp;&nbsp;&nbsp; try:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; shutil.rmtree(server_dir)<br />&nbsp;&nbsp;&nbsp; except:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pass<br />&nbsp;&nbsp;&nbsp; print("Delete " + client_dir)<br />&nbsp;&nbsp;&nbsp; try:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; shutil.rmtree(client_dir)<br />&nbsp;&nbsp;&nbsp; except:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pass&nbsp;&nbsp; &nbsp;<br /><br />&nbsp;&nbsp;&nbsp; # 生成server文件<br />&nbsp;&nbsp;&nbsp; print("Creating " + server_dir)<br />&nbsp;&nbsp;&nbsp; shutil.copytree(design_dir, server_dir)<br />&nbsp;&nbsp;&nbsp; files = get_files(server_dir)<br />&nbsp;&nbsp;&nbsp; convert_files(files)<br />&nbsp;&nbsp; &nbsp;<br />&nbsp;&nbsp;&nbsp; # 复制client文件<br />&nbsp;&nbsp;&nbsp; print("Copy " + client_dir)<br />&nbsp;&nbsp;&nbsp; shutil.copytree(server_dir, client_dir)<br />&nbsp;&nbsp;&nbsp; shutil.rmtree(os.path.join(client_dir, 'server/'))<br />&nbsp;&nbsp;&nbsp; print("Done. Total files: %d" % len(files))<br /># End of datatab_convert().&nbsp;&nbsp; &nbsp;<br /><br />def get_files(dir):<br />&nbsp;&nbsp;&nbsp; '''Get a list of files under input dir.'''<br />&nbsp;&nbsp;&nbsp; result = []<br />&nbsp;&nbsp;&nbsp; for root,dirs,files in os.walk(dir):<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for f in files:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; result.append(os.path.join(root, f))<br />&nbsp;&nbsp;&nbsp; return result<br /># End of get_files().&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br /><br />def convert_files(files):<br />&nbsp;&nbsp;&nbsp; '''转换一批文件.<br />&nbsp;&nbsp;&nbsp; files 是列表，元素为完整路径名。<br />&nbsp;&nbsp;&nbsp; '''<br />&nbsp;&nbsp;&nbsp; for f in files:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ext = os.path.splitext(f)[1].lower()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if '.xlsx' != ext:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print(f + " -&gt; keep")<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; continue<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print(f + " -&gt; csv")<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; xlsx2csv(f)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; os.remove(f)<br /># End of convert_files().&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;<br /><br />if __name__ == '__main__':<br />&nbsp;&nbsp;&nbsp; if len(sys.argv) != 2:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print('usage: datatab &lt;game dir&gt;')<br />&nbsp;&nbsp;&nbsp; else:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; datatab_convert(sys.argv[1])<br />&nbsp;&nbsp;&nbsp; sys.exit(0)</span><br /><br /># Usage: datatab.py &lt;game dir&gt;<br /># Example: datatab.py "d:\game"<br /># &lt;game dir&gt; 是SVN根目录，包含Design/, Program/ 目录。<br /><br />为方便使用，将datatab.py 打包成 exe, 这样不能安装Python就能运行。<br />下载并安装Python3, 安装openpyxl包，保证本地可以运行 datatab.py.<br />下载并安装PyInstaller：<br />&nbsp;&nbsp;&nbsp; pip install pyinstaller<br />运行<br />&nbsp;&nbsp;&nbsp; pyinstaller --onefile datatab.py<br /><br />ImportError: No module named 'jdcal'<br />可能openpyxl安装时自带的jdcal无法找到，删除 <br />C:\Python34\Lib\site-packages\jdcal-1.0-py3.4.egg<br />重新安装：pip install jdcal<br />&nbsp;&nbsp;&nbsp; </div><img src ="http://www.cppblog.com/jinq0123/aggbug/212153.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2015-10-30 16:05 <a href="http://www.cppblog.com/jinq0123/archive/2015/10/30/212153.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>如何运行 rpcz python example </title><link>http://www.cppblog.com/jinq0123/archive/2013/12/11/204705.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Wed, 11 Dec 2013 02:12:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2013/12/11/204705.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/204705.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2013/12/11/204705.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/204705.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/204705.html</trackback:ping><description><![CDATA[<div>试着运行 rpcz-python 的 example。过程记录如下。<br /><br />假设protobuf-py已经按照protobuf的安装说明安装了。<br />发现 protobuf-2.5.0版的python包是python2的，没有找到python3的。<br />试着2to3.py转换一下，结果转换后无法安装。<br />只好将python3.3换成python2.7<br /><br />python2.7的mimetypes.py有错误，注册表中HKEY_CLASSES_ROOT有中文的扩展名时，<br />安装setuptools失败，参考 http://www.oschina.net/question/1409342_134600<br /><br />先编译 rpz, 将生成的 <br />protoc-gen-cpp_rpcz.exe<br />protoc-gen-python_rpcz.exe<br />复制到系统搜索目录，如与protoc.exe放在一起。<br /><br />进入 rpcz 的 python 目录，运行<br />python setup.py install<br /><br />出现如下的各种错误：<br /><span style="color:#FF0000;">../include\rpcz/connection_manager.hpp(21) : fatal error C1083: Cannot open incl<br />ude file: 'boost/function.hpp': No such file or directory<br />../include\rpcz/macros.hpp(20) : fatal error C1083: Cannot open include file: 'g<br />oogle/protobuf/stubs/common.h': No such file or directory<br />../include\rpcz/rpc.hpp(24) : fatal error C1083: Cannot open include file: 'rpcz<br />/rpcz.pb.h': No such file or directory<br />LINK : fatal error LNK1181: cannot open input file 'rpcz.lib'<br />LINK : fatal error LNK1104: cannot open file 'libboost_thread-vc100-mt-1_54.lib'<br /></span><br />直接改了setup.py如下。<br /><br /><span style="color:#660000;">&nbsp;&nbsp;&nbsp; ext_modules=[<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Extension("rpcz.pywraprpcz", ["cython/pywraprpcz.cpp"],<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; libraries=["rpcz", "libprotobuf", "libzmq"],<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; include_dirs=['../include', '../build/src',<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 'D:/Boost/include/boost-1_54',<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 'G:/workspace/rpcz_jinq/src',<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 'D:/LibSrc/protobuf-2.5.0/vsprojects/include'],<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; library_dirs=['../build/deps/lib', '../build/src/rpcz',<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 'D:/Boost/lib',<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 'G:/workspace/rpcz_jinq/src/rpcz/Release',<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 'D:/LibSrc/zeromq-4.0.3/builds/msvc/Release',<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 'D:/LibSrc/protobuf-2.5.0/vsprojects/Release'],<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; language='c++')<br />&nbsp;&nbsp;&nbsp; ],</span><br /><br />不知道如何做成通用的脚本。<br />rpcz原来应该是建立一个固定位置的build目录，其中有deps目录，包含所有库。<br />这就要求cmake的构建目录固定为build.<br />&nbsp;<br />python2.7是用VC2008编译的，用VC2010编译python扩展会有问题。<br />会报错：<br /><span style="color:#FF0000;">error: Unable to find vcvarsall.bat</span><br />强制使用VC2010:<br />SET VS90COMNTOOLS=%VS100COMNTOOLS%<br />参考：http://stackoverflow.com/questions/2817869/error-unable-to-find-vcvarsall-bat<br /><br />最后进入 examples\python，先 generate_protos.gy 生成消息和接口，然后运行 server, client.<br />运行时需要 libzmq.dll, rpcz.dll.</div><img src ="http://www.cppblog.com/jinq0123/aggbug/204705.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2013-12-11 10:12 <a href="http://www.cppblog.com/jinq0123/archive/2013/12/11/204705.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Windows上Python读取stdin出错</title><link>http://www.cppblog.com/jinq0123/archive/2012/04/11/170873.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Wed, 11 Apr 2012 02:56:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2012/04/11/170873.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/170873.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2012/04/11/170873.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/170873.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/170873.html</trackback:ping><description><![CDATA[<div>Windows上Python读取stdin出错<br /><br />（金庆的专栏）<br /><br />一段简单的代码，读取stdin, 替换输出到stdout:<br /><br />#!/usr/bin/env python<br />import os, sys<br />input_file = sys.stdin<br />output_file = sys.stdout<br />for s in input_file:<br />&nbsp;&nbsp;&nbsp; output_file.write(s.replace("abc", "def"))<br /><br />代码改自CookBook的&nbsp;&nbsp; &nbsp;<br />Recipe 2.3. Searching and Replacing Text in a File<br /><br />在Linux上运行正常：<br />$ cat input.txt | ./replace.py<br />&nbsp;<br />但是在Windows的Dos窗口运行会报错：<br />&gt; type input.txt | replace.py<br />Traceback...<br />&nbsp;&nbsp;&nbsp; for s in input_file:<br />IOError: [Errno 9] Bad file descriptor<br /><br />如果用python调用就正常：<br />&gt; type input.txt | python replace.py<br /><br />原因是cmd.exe通过后缀关联运行py文件存在问题。<br />详见：Bad pipe filedescriptor when reading from stdin in python<br />http://stackoverflow.com/questions/1057638/bad-pipe-filedescriptor-when-reading-from-stdin-in-python<br /><br />It seems that stdin/stdout redirect does not work when starting from a file association. This is not specific to python, but a problem caused by win32 cmd.exe.<br /></div><img src ="http://www.cppblog.com/jinq0123/aggbug/170873.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2012-04-11 10:56 <a href="http://www.cppblog.com/jinq0123/archive/2012/04/11/170873.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>建立Socket Policy服务器</title><link>http://www.cppblog.com/jinq0123/archive/2012/01/19/164375.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Thu, 19 Jan 2012 08:21:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2012/01/19/164375.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/164375.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2012/01/19/164375.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/164375.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/164375.html</trackback:ping><description><![CDATA[<div>建立Socket Policy服务器<br /><br />（金庆的专栏）<br /><br />Flash和Unity3D游戏服务器需要开启一个Socket Policy服务器。<br />详细说明见：Setting up a socket policy file server<br />http://www.adobe.com/devnet/flashplayer/articles/socket_policy_files.html<br /><br />协议如下：<br />Flash或U3D播放器向Socket Policy服务器发送请求：<br />&#8220;&lt;policy-file-request/&gt;\0&#8221;，<br />服务器返回一个xml文本，其中有包含&lt;cross-domain-policy&gt;配置。<br /><br />Adobe提供了Perl和Python代码。Unity3D提供了CSharp代码。<br />cs代码用于Windows. Linux上准备使用Python代码。<br />在以上网页下载：flashpolicyd_v0.6.zip。<br />其中有3个版本：init服务，xinetd服务，独立应用。只需一种即可。<br /><br />按应用的性质，请求量极小，所以最适合应用xinetd.<br />只需运行其中的install.sh就会安装。<br />还需手工在/ect/services中添加服务名flashpolicy和端口843.<br /><br />运行以下指令可以测试一下，输出应该是配置文件的内容。<br />python -c 'print "&lt;policy-file-request/&gt;%c" % 0' | nc 127.0.0.1 843<br /><br />其实以上测试指令在尾部多了个'\n', 不是标准的测试。<br />在in.flashpolicyd.py中多了个strip()去除这个'\n'.<br /><br />实际用U3D测试时，因为没有'\n'结尾，所以in.flashpolicyd.py无法正常工作。<br />需要将35行readline()如下更改：<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; request = sys.stdin.readline().strip()<br />改为<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; request = sys.stdin.readline(len('&lt;policy-file-request/&gt;\0')).strip()<br />这样就不需要eol就可以读取了。<br /><br />查看其他两个版本的代码没有这个错误，但是有另一个错误，<br />即有可能只读一半的请求造成判断出错。<br /><br />还有一个问题是因为服务是由nobody运行的，环境变量不同，<br />将in.flashpolicyd.py头部的<br />#!/usr/bin/env python<br />明确为<br />#!/usr/local/sbin/python<br />可避免调用低版本的python而报错。<br /></div><img src ="http://www.cppblog.com/jinq0123/aggbug/164375.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2012-01-19 16:21 <a href="http://www.cppblog.com/jinq0123/archive/2012/01/19/164375.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>python计算24点</title><link>http://www.cppblog.com/jinq0123/archive/2010/12/22/137212.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Wed, 22 Dec 2010 10:56:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2010/12/22/137212.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/137212.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2010/12/22/137212.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/137212.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/137212.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 输入4个数字, 输出所有用加减乘除结果为24的表达式. 代码如下:&nbsp;&nbsp;<a href='http://www.cppblog.com/jinq0123/archive/2010/12/22/137212.html'>阅读全文</a><img src ="http://www.cppblog.com/jinq0123/aggbug/137212.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2010-12-22 18:56 <a href="http://www.cppblog.com/jinq0123/archive/2010/12/22/137212.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>(Python编程)Pickle对象</title><link>http://www.cppblog.com/jinq0123/archive/2009/07/03/89167.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Fri, 03 Jul 2009 08:37:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2009/07/03/89167.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/89167.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2009/07/03/89167.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/89167.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/89167.html</trackback:ping><description><![CDATA[<p>Programming Python, 3rd Edition 翻译<br>最新版本见：<a href="http://wiki.woodpecker.org.cn/moin/PP3eD">http://wiki.woodpecker.org.cn/moin/PP3eD</a>
<br></p>
<p><br></p>
<p>19.4. Pickled Objects <br>
<br>
19.4. Pickle对象 <br>
<br>
</p>
<p>Probably
the biggest limitation of DBM keyed files is in what they can store:
data stored under a key must be a simple text string. If you want to
store Python objects in a DBM file, you can sometimes manually convert
them to and from strings on writes and reads (e.g., with str and eval
calls), but this takes you only so far. For arbitrarily complex Python
objects such as class instances and nested data structures, you need
something more. Class instance objects, for example, cannot be later
re-created from their standard string representations. Custom to-string
conversions are error prone and not general. <br>
<br>
</p>
<p>DBM
键控文件（DBM keyed
file）最大的限制也许在于他们可以存储的东西：一个键值下存储的数据必须是个简单文本字符串。如果您想要在DBM文件中储存Python对象，有时您
可以在读写的时候，手动进行与字符串的转换（例如，用str和eval调用），但只能做到这样。对任意复杂的Python对象，如类实例和嵌套的数据结
构，您需要更多的东西。例如，类实例对象以后无法从其标准字符串表达（string
representation）重建。自定义的到字符串的转换容易出错，并且不通用。 <br>
<br>
</p>
<p>The
Python pickle module, a standard part of the Python system, provides
the conversion step needed. It converts nearly arbitrary Python
in-memory objects to and from a single linear string format, suitable
for storing in flat files, shipping across network sockets between
trusted sources, and so on. This conversion from object to string is
often called serializationarbitrary data structures in memory are
mapped to a serial string form. <br>
<br>
</p>
<p>Python
系统的标准部件，pickle模块，提供了所需的转换步骤。它可以将几乎任意的Python内存对象，转换为单一线性的字符串格式，使之适于无格式文件存
储，或在可靠来源之间跨越网络套接口传输等等，并可反向转换。这种从对象到字符串的转换通常被称为序列化（serialization）：将内存中的任意
数据结构映射为串行字符串形式。 <br>
<br>
</p>
<p>The
string representation used for objects is also sometimes referred to as
a byte stream, due to its linear format. It retains all the content and
references structure of the original in-memory object. When the object
is later re-created from its byte string, it will be a new in-memory
object identical in structure and value to the original, though located
at a different memory address. The re-created object is effectively a
copy of the original. <br>
<br>
</p>
<p>对象的字符串表达由于其线性的格式，有时也被称为字节流。它包含了原始内存中对象的所有内容和引用结构。当对象后来从其字节串重建时，内存中新建的对象与原对象具有相同的结构和值，但位于不同的内存地址。该重建对象实际上是原对象的复制。 <br>
<br>
</p>
<p>Pickling
works on almost any Python datatypenumbers, lists, dictionaries, class
instances, nested structures, and moreand so is a general way to store
data. Because pickles contain native Python objects, there is almost no
database API to be found; the objects stored are processed with normal
Python syntax when they are later retrieved. <br>
<br>
</p>
<p>Pickle可用于几乎所有的Python数据类型：数字、列表、字典、类实例、嵌套结构，等等，因此它是存储数据的通用方法。因为pickle包含的是Python本地对象，所以几乎没有数据库的API；对象存储与处理及后来的提取用的都是通常的Python语法。 <br>
<br>
</p>
<p>19.4.1. Using Object Pickling <br>
<br>
</p>
<p>19.4.1. 使用对象pickle <br>
<br>
</p>
<p>Pickling
may sound complicated the first time you encounter it, but the good
news is that Python hides all the complexity of object-to-string
conversion. In fact, the pickle module 's interfaces are incredibly
simple to use. For example, to pickle an object into a serialized
string, we can either make a pickler and call its methods or use
convenience functions in the module to achieve the same effect: <br>
<br>
</p>
<p>第
一次听到pickle，可能觉得有点复杂，但好消息是，Python隐藏了所有从对象到字符串转换的复杂性。事实上，pickle模块的接口简单易用，简
直令人难以置信。例如，要pickle对象到一个序列化字符串，我们可以生成一个pickler，并调用其方法，或使用模块中的便捷函数来达到相同的效
果： <br>
<br>
</p>
<p>&#160;</p>
<pre>P = pickle.Pickler( file) <br></pre>
<p>Make a new pickler for pickling to an open output file object file. <br>
生成一个新的pickler，用来pickle到一个打开的输出文件对象file。 <br>
<br>
</p>
<p>&#160;</p>
<pre>P.dump( object) <br></pre>
<p>Write an object onto the pickler's file/stream. <br>
写一个对象到pickler的文件/流。 <br>
<br>
</p>
<p>&#160;</p>
<pre>pickle.dump( object, file) <br></pre>
<p>Same as the last two calls combined: pickle an object onto an open file. <br>
等同于上两个调用的组合：pickle对象到一个打开的文件。 <br>
<br>
</p>
<p>&#160;</p>
<pre>string = pickle.dumps( object) <br></pre>
<p>Return the pickled representation of object as a character string. <br>
返回一个字符串作为已pickle对象的表达。 <br>
<br>
</p>
<p>Unpickling
from a serialized string back to the original object is similarboth
object and convenience function interfaces are available: <br>
<br>
</p>
<p>从一个序列化字符串unpickle回原始对象是类似的，可以用对象也可以用便捷函数接口： <br>
<br>
</p>
<p>&#160;</p>
<pre>U = pickle.Unpickler( file) <br></pre>
<p>Make an unpickler for unpickling from an open input file object file. <br>
生成一个unpickler，用来从一个打开的文件对象file unpickle。 <br>
<br>
</p>
<p>&#160;</p>
<pre>object = U.load( )<br></pre>
<p>Read an object from the unpickler's file/stream. <br>
从unpickler的文件/流读取一个对象。 <br>
<br>
</p>
<p>&#160;</p>
<pre>object = pickle.load( file) <br></pre>
<p>Same as the last two calls combined: unpickle an object from an open file. <br>
等同于上两个调用的组合：从一个打开的文件unpickle一个对象。 <br>
<br>
</p>
<p>&#160;</p>
<pre>object = pickle.loads( string) <br></pre>
<p>Read an object from a character string rather than a file. <br>
从字符串读取一个对象，而不是从文件。 <br>
<br>
</p>
<p>Pickler
and Unpickler are exported classes. In all of the preceding cases, file
is either an open file object or any object that implements the same
attributes as file objects: <br>
<br>
</p>
<p>Pickler和Unpickler是导出类。在上述所有情况下，file是个已打开的文件对象，或者是实现了以下文件对象属性的任何对象： <br>
<br>
</p>
<p>Pickler calls the file's write method with a string argument. <br>
<br>
</p>
<p>Pickler会调用文件的write方法，参数是个字符串。 <br>
<br>
</p>
<p>Unpickler calls the file's read method with a byte count, and readline without arguments. <br>
<br>
</p>
<p>Unpickler会调用文件的read方法，参数是字节数，以及readline，无参数。 <br>
<br>
</p>
<p>Any
object that provides these attributes can be passed in to the file
parameters. In particular, file can be an instance of a Python class
that provides the read/write methods (i.e., the expected file-like
interface). This lets you map pickled streams to in-memory objects with
classes, for arbitrary use. For instance, the StringIO standard library
module discussed in Chapter 3 provides classes that map file calls to
and from in-memory strings. <br>
<br>
</p>
<p>任
何提供这些属性的对象都可以作为file参数传入。特别是，file可以是一个提供了读/写方法的Python类实例（即预期的类似文件的接口）。这让您
可以用类映射pickle流到内存对象，并可任意使用。例如，第3章讨论的标准库模块StringIO提供的类，它们可映射文件调用到内存字符串或反之。
<br>
<br>
</p>
<p>This
hook also lets you ship Python objects across a network, by providing
sockets wrapped to look like files in pickle calls at the sender, and
unpickle calls at the receiver (see the sidebar "Making Sockets Look
Like Files," in Chapter 13, for more details). In fact, for some,
pickling Python objects across a trusted network serves as a simpler
alternative to network transport protocols such as SOAP and XML-RPC;
provided that Python is on both ends of the communication (pickled
objects are represented with a Python-specific format, not with XML
text). <br>
<br>
</p>
<p>该
挂钩也可以让您通过网络传输Python对象，只要封装套接口，使之看上去像发送端pickle调用中的文件，以及像接收端unpickle调用中的文件
（详见第13章侧栏&#8220;使套接口看上去像文件&#8221;）。事实上，对一些人来说，pickle
Python对象并在一个值得信赖的网络上传输，是替代如SOAP和XML-RPC之类网络传输协议的一个简单方法；只要通信的两端都有Python（被
pickle的对象是用Python专有的格式表达的，而不是用XML文本）。 <br>
<br>
</p>
<p>19.4.2. Picking in Action <br>
<br>
</p>
<p>19.4.2. Pickle实战 <br>
<br>
</p>
<p>In more typical use, to pickle an object to a flat file, we just open the file in write mode and call the dump function: <br>
<br>
</p>
<p>典型的使用情况是，pickle对象到无格式文件，我们只需以写模式打开文件，并调用dump函数： <br>
<br>
</p>
<p>&#160;</p>
<pre>% python<br>&gt;&gt;&gt; table = {'a': [1, 2, 3],<br>             'b': ['spam', 'eggs'],<br>             'c': {'name':'bob'}}<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; import pickle<br>&gt;&gt;&gt; mydb  = open('dbase', 'w')<br>&gt;&gt;&gt; pickle.dump(table, mydb)<br></pre>
<p><br>
<br>
</p>
<p>Notice
the nesting in the object pickled herethe pickler handles arbitrary
structures. To unpickle later in another session or program run, simply
reopen the file and call load: <br>
<br>
</p>
<p>注意这个被pickle对象中的嵌套：pickler可以处理任意结构。然后，在另一个会话或程序中unpickle，只要重新打开该文件，并调用load： <br>
<br>
</p>
<p>&#160;</p>
<pre>% python<br>&gt;&gt;&gt; import pickle<br>&gt;&gt;&gt; mydb  = open('dbase', 'r')<br>&gt;&gt;&gt; table = pickle.load(mydb)<br>&gt;&gt;&gt; table<br>{'b': ['spam', 'eggs'], 'a': [1, 2, 3], 'c': {'name': 'bob'}}<br></pre>
<p><br>
<br>
</p>
<p>The
object you get back from unpickling has the same value and reference
structure as the original, but it is located at a different address in
memory. This is true whether the object is unpickled in the same or a
future process. In Python-speak, the unpickled object is == but is not
is: <br>
<br>
</p>
<p>unpickle所得的对象具有与原对象相同的值和引用结构，但它位于不同的内存地址。无论在同一进程或另一进程unpickle，都是这样。用Python的话来说，unpickle后的对象是&#8220;==&#8221;关系，但不是&#8220;is&#8221;关系： <br>
<br>
</p>
<p>&#160;</p>
<pre>% python<br>&gt;&gt;&gt; import pickle<br>&gt;&gt;&gt; f = open('temp', 'w')<br>&gt;&gt;&gt; x = ['Hello', ('pickle', 'world')]           # list with nested tuple<br>&gt;&gt;&gt; pickle.dump(x, f)<br>&gt;&gt;&gt; f.close( )                                   # close to flush changes<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; f = open('temp', 'r')<br>&gt;&gt;&gt; y = pickle.load(f)<br>&gt;&gt;&gt; y<br>['Hello', ('pickle', 'world')]<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; x == y, x is y<br>(True, False)<br></pre>
<p><br>
<br>
</p>
<p>To
make this process simpler still, the module in Example 19-1 wraps
pickling and unpickling calls in functions that also open the files
where the serialized form of the object is stored. <br>
<br>
</p>
<p>为了让这一过程更简单，例19-1中的模块把pickle和unpickle调用封装在函数中，在函数中同时还打开文件，并将对象的序列化存储在该文件中。 <br>
<br>
</p>
<p>Example 19-1. PP3E\Dbase\filepickle.py </p>
<div class="codearea" dir="ltr" lang="en">
<script type="text/javascript">
function isnumbered(obj) {
  return obj.childNodes.length && obj.firstChild.childNodes.length && obj.firstChild.firstChild.className == 'LineNumber';
}
function nformat(num,chrs,add) {
  var nlen = Math.max(0,chrs-(''+num).length), res = '';
  while (nlen>0) { res += ' '; nlen-- }
  return res+num+add;
}
function addnumber(did, nstart, nstep) {
  var c = document.getElementById(did), l = c.firstChild, n = 1;
  if (!isnumbered(c))
    if (typeof nstart == 'undefined') nstart = 1;
    if (typeof nstep  == 'undefined') nstep = 1;
    n = nstart;
    while (l != null) {
      if (l.tagName == 'SPAN') {
        var s = document.createElement('SPAN');
        s.className = 'LineNumber'
        s.appendChild(document.createTextNode(nformat(n,4,' ')));
        n += nstep;
        if (l.childNodes.length)
          l.insertBefore(s, l.firstChild)
        else
          l.appendChild(s)
      }
      l = l.nextSibling;
    }
  return false;
}
function remnumber(did) {
  var c = document.getElementById(did), l = c.firstChild;
  if (isnumbered(c))
    while (l != null) {
      if (l.tagName == 'SPAN' && l.firstChild.className == 'LineNumber') l.removeChild(l.firstChild);
      l = l.nextSibling;
    }
  return false;
}
function togglenumber(did, nstart, nstep) {
  var c = document.getElementById(did);
  if (isnumbered(c)) {
    remnumber(did);
  } else {
    addnumber(did,nstart,nstep);
  }
  return false;
}
</script>
<script type="text/javascript">
document.write('<a href="#" href_cetemp="#" onclick="return togglenumber(\'ca-fb42528cb4c20d066e06b836307a75fa8e016e1b_000\', 1, 1);" \
                class="codenumbers">切换行号显示<\/a>');
</script>
<pre dir="ltr" id="CA-fb42528cb4c20d066e06b836307a75fa8e016e1b_000" lang="en">   1 import pickle<br>   2 <br>   3 def saveDbase(filename, object):<br>   4     file = open(filename, 'w')<br>   5     pickle.dump(object, file)          # pickle to file<br>   6     file.close( )                     # any file-like object will do<br>   7 <br>   8 def loadDbase(filename):<br>   9     file = open(filename, 'r')<br>  10     object = pickle.load(file)         # unpickle from file<br>  11     file.close( )                     # re-creates object in memory<br>  12     return object<br></pre>
</div>
<p><br>
<br>
</p>
<p>To
store and fetch now, simply call these module functions; here they are
in action managing a fairly complex structure with multiple references
to the same nested objectthe nested list called L at first is stored
only once in the file: <br>
<br>
</p>
<p>现在，存储和提取时只需调用这些模块函数；以下实例是个相当复杂的结构，具有对同一嵌套对象的多重引用，该嵌套列表，即第1个L，在文件中只会保存一次： <br>
<br>
</p>
<p>&#160;</p>
<pre>C:\...\PP3E\Dbase&gt;python<br>&gt;&gt;&gt; from filepickle import *<br>&gt;&gt;&gt; L = [0]<br>&gt;&gt;&gt; D = {'x':0, 'y':L}<br>&gt;&gt;&gt; table = {'A':L, 'B':D}              # L appears twice<br>&gt;&gt;&gt; saveDbase('myfile', table)          # serialize to file<br><br>C:\...\PP3E\Dbase&gt;python<br>&gt;&gt;&gt; from filepickle import *<br>&gt;&gt;&gt; table = loadDbase('myfile')         # reload/unpickle<br>&gt;&gt;&gt; table<br>{'B': {'x': 0, 'y': [0]}, 'A': [0]}<br>&gt;&gt;&gt; table['A'][0] = 1                   # change shared object<br>&gt;&gt;&gt; saveDbase('myfile', table)          # rewrite to the file<br><br>C:\...\PP3E\Dbase&gt;python<br>&gt;&gt;&gt; from filepickle import *<br>&gt;&gt;&gt; print loadDbase('myfile')           # both L's updated as expected<br>{'B': {'x': 0, 'y': [1]}, 'A': [1]}<br></pre>
<p><br>
<br>
</p>
<p>Besides
built-in types like the lists, tuples, and dictionaries of the examples
so far, class instances may also be pickled to file-like objects. This
provides a natural way to associate behavior with stored data (class
methods process instance attributes) and provides a simple migration
path (class changes made in module files are automatically picked up by
stored instances). Here's a brief interactive demonstration: <br>
<br>
</p>
<p>除
了内置的类型，如以上例子中的列表，元组和字典，类实例也可被pickle到类似文件的对象中。这提供了一个自然的方式来关联行为与存储的数据（类方法处
理实例的属性），并提供了一条简单的迁移路径（被存储的实例将自动获得模块文件中对类的更改）。以下是个简短的交互演示： <br>
<br>
</p>
<p>&#160;</p>
<pre>&gt;&gt;&gt; class Rec:<br>        def _ _init_ _(self, hours):<br>            self.hours = hours<br>        def pay(self, rate=50):<br>            return self.hours * rate<br><br>&gt;&gt;&gt; bob = Rec(40)<br>&gt;&gt;&gt; import pickle<br>&gt;&gt;&gt; pickle.dump(bob, open('bobrec', 'w'))<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; rec = pickle.load(open('bobrec'))<br>&gt;&gt;&gt; rec.hours<br>40<br>&gt;&gt;&gt; rec.pay( )<br>2000<br></pre>
<p><br>
<br>
</p>
<p>We'll
explore how this works in more detail in conjunction with shelves later
in this chapteras we'll see, although the pickle module can be used
directly, it is also the underlying translation engine in both shelves
and ZODB databases. <br>
<br>
</p>
<p>我们将与本章下面的shelve一起详细探讨这是如此工作的。我们将会看到，虽然pickle模块可直接使用，但它也是shelve和ZODB数据库的底层翻译引擎。 <br>
<br>
</p>
<p>In fact, Python can pickle just about anything, except for: <br>
<br>
</p>
<p>事实上，Python可以pickle任何东西，除了： <br>
<br>
</p>
<p>Compiled
code objects; functions and classes record just their names in pickles,
to allow for later reimport and automatic acquisition of changes made
in module files. <br>
<br>
</p>
<p>编译的代码对象；函数和类在pickle中只是记录了它们的名字，以便后来重新导入和自动获取模块文件中的更改。 <br>
<br>
</p>
<p>Instances
of classes that do not follow class importability rules (more on this
at the end of the section "Shelve Files," later in this chapter). <br>
<br>
</p>
<p>不遵守类可导入规则（class importability rule）的类实例（本章后面&#8220;Shelve文件&#8221;一节的尾部有更多相关内容）。 <br>
<br>
</p>
<p>Instances
of some built-in and user-defined types that are coded in C or depend
upon transient operating system states (e.g., open file objects cannot
be pickled). <br>
<br>
</p>
<p>用C编码的或依赖于操作系统瞬态的一些内置的和用户定义类型的实例（例如，打开的文件对象无法pickle）。 <br>
<br>
</p>
<p>A <a class="nonexistent" href="http://wiki.woodpecker.org.cn/moin/PicklingError">PicklingError</a> is raised if an object cannot be pickled. <br>
<br>
</p>
<p>如果对象不能pickle，会引发<a class="nonexistent" href="http://wiki.woodpecker.org.cn/moin/PickleError">PickleError</a>。 <br>
<br>
</p>
<p>19.4.3. Pickler Protocols and cPickle <br>
<br>
</p>
<p>19.4.3. Pickler协议和cPickle <br>
<br>
</p>
<p>In
recent Python releases, the pickler introduced the notion of
protocolsstorage formats for pickled data. Specify the desired protocol
by passing an extra parameter to the pickling calls (but not to
unpickling calls: the protocol is automatically determined from the
pickled data): <br>
<br>
</p>
<p>在最近的Python版本中，pickler推出了协议的概念：pickle数据的保存格式。通过pickle调用时传入一个额外的参数，可指定所需的协议（但unpickle调用不需要：协议是自动从已pickle的数据确定的）： <br>
<br>
</p>
<p>&#160;</p>
<pre>pickle.dump(object, file, protocol)<br></pre>
<p><br>
<br>
</p>
<p>Pickled
data may be created in either text or binary protocols. By default, the
storage protocol is text (also known as protocol 0). In text mode, the
files used to store pickled objects may be opened in text mode as in
the earlier examples, and the pickled data is printable ASCII text,
which can be read (it's essentially instructions for a stack machine). <br>
<br>
</p>
<p>Pickle
数据可以按文本协议或二进制协议产生。默认情况下，存储协议是文本协议（也称为0号协议）。在文本模式下，用来存储pickle对象的文件可以用文本模式
打开，如上述的例子，并且pickle的数据是可打印的ASCII文本，并且是可读的（这基本上是对堆栈机实现的指示）。 <br>
<br>
</p>
<p>The
alternative protocols (protocols 1 and 2) store the pickled data in
binary format and require that files be opened in binary mode (e.g.,
rb, wb). Protocol 1 is the original binary format; protocol 2, added in
Python 2.3, has improved support for pickling of new-style classes.
Binary format is slightly more efficient, but it cannot be inspected.
An older option to pickling calls, the bin argument, has been subsumed
by using a pickling protocol higher than 0. The pickle module also
provides a HIGHEST_PROTOCOL variable that can be passed in to
automatically select the maximum value. <br>
<br>
</p>
<p>其
他协议（1号和2号协议
）以二进制格式存储pickle数据，并要求文件以二进制模式打开（例如：rb、wb）。1号协议是原始二进制格式；2号协议是Python
2.3增加的，它改善了对新型类pickle的支持。二进制格式效率更高一点，但它无法进行查看。旧的pickle调用有一个选项，即bin参数，现已被
归入使用大于0的协议。pickle模块还提供了一个HIGHEST_PROTOCOL变量，传入它可以自动选择最大的协议值。 <br>
<br>
</p>
<p>One
note: if you use the default text protocol, make sure you open pickle
files in text mode later. On some platforms, opening text data in
binary mode may cause unpickling errors due to line-end formats on
Windows: <br>
<br>
</p>
<p>注意：如果您使用默认的文本协议，以后请务必以文本模式打开pickle文件。在一些平台上，因为Windows的行尾格式不同，以二进制模式打开文本数据可能会导致unpickle错误: <br>
<br>
</p>
<p>&#160;</p>
<pre>&gt;&gt;&gt; f = open('temp', 'w')                  # text mode file on Windows<br>&gt;&gt;&gt; pickle.dump(('ex', 'parrot'), f)       # use default text protocol<br>&gt;&gt;&gt; f.close( ) <br>&gt;&gt;&gt;<br>&gt;&gt;&gt; pickle.load(open('temp', 'r'))         # OK in text mode<br>('ex', 'parrot')<br>&gt;&gt;&gt; pickle.load(open('temp', 'rb'))        # fails in binary<br>Traceback (most recent call last):<br>  File "&lt;pyshell#337&gt;", line 1, in -toplevel-<br>    pickle.load(open('temp', 'rb'))<br> ...lines deleted...<br>ValueError: insecure string pickle<br></pre>
<p><br>
<br>
</p>
<p>One
way to sidestep this potential issue is to always use binary mode for
your files, even for the text pickle protocol. Since you must open
files in binary mode for the binary pickler protocols anyhow (higher
than the default 0), this isn't a bad habit to get into: <br>
<br>
</p>
<p>回避这个潜在问题的方法之一是，总是使用二进制模式的文件，即使是用文本pickle协议。至少对于二进制pickler协议（高于默认0），您必须以二进制模式打开文件，所以这不是一个坏习惯： <br>
<br>
</p>
<p>&#160;</p>
<pre>&gt;&gt;&gt; f = open('temp', 'wb')                 # create in binary mode<br>&gt;&gt;&gt; pickle.dump(('ex', 'parrot'), f)       # use text protocol<br>&gt;&gt;&gt; f.close( )<br>&gt;&gt;&gt;<br>&gt;&gt;&gt; pickle.load(open('temp', 'rb'))<br>('ex', 'parrot')<br>&gt;&gt;&gt; pickle.load(open('temp', 'r'))<br>('ex', 'parrot')<br></pre>
<p><br>
<br>
</p>
<p>Refer
to Python's library manual for more information on the pickler. Also
check out marshal, a module that serializes an object too, but can
handle only simple object types. pickle is more general than marshal
and is normally preferred. <br>
<br>
</p>
<p>请参考Python库手册，以了解更多pickler的信息。另外，请查阅marshal，它也是一个序列化对象的模块，但只能处理简单对象类型。pickle比marshal更通用，并通常是首选。 <br>
<br>
</p>
<p>And
while you are flipping (or clicking) through that manual, be sure to
also see the entries for the cPickle modulea reimplementation of pickle
coded in C for faster performance. You can explicitly import cPickle
for a substantial speed boost; its chief limitation is that you cannot
subclass its versions of Pickle and Unpickle because they are
functions, not classes (this is not required by most programs). The
pickle and cPickle modules use compatible data formats, so they may be
used interchangeably. <br>
<br>
</p>
<p>而
当你翻看（或点击）Python手册时，请一定也要看看cPickle模块的条目，它是pickle的C语言实现，性能上更快。您可以显式导入
cPickle替代pickle，以大幅提升速度；其主要的限制是，你不能继承该版本的Pickle和Unpickle，因为它们是函数，而不是类（多数
程序并不要求它们是类）。pickle和cPickle模块使用兼容的数据格式，所以它们可以互换使用。 <br>
<br>
</p>
<p>If
it is available in your Python, the shelve module automatically chooses
the cPickle module for faster serialization, instead of pickle. I
haven't explained shelve yet, but I will now. <br>
<br>
</p>
如果您的Python中有shelve模块，它会自动选用cPickle模块，而不是pickle，以达到更快的序列化。我还没有解释过shelve，但我马上就会讲到它。 <br>
<br><img src ="http://www.cppblog.com/jinq0123/aggbug/89167.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2009-07-03 16:37 <a href="http://www.cppblog.com/jinq0123/archive/2009/07/03/89167.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Boost.Python中文文档下载</title><link>http://www.cppblog.com/jinq0123/archive/2008/06/16/BoostPythonDocTranslate.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Mon, 16 Jun 2008 03:30:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2008/06/16/BoostPythonDocTranslate.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/53516.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2008/06/16/BoostPythonDocTranslate.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/53516.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/53516.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 下载：Boost.Python中文文档<br>Boost文档中Python库文档的翻译。&nbsp;&nbsp;<a href='http://www.cppblog.com/jinq0123/archive/2008/06/16/BoostPythonDocTranslate.html'>阅读全文</a><img src ="http://www.cppblog.com/jinq0123/aggbug/53516.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2008-06-16 11:30 <a href="http://www.cppblog.com/jinq0123/archive/2008/06/16/BoostPythonDocTranslate.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用Boost.Python构建混合系统</title><link>http://www.cppblog.com/jinq0123/archive/2008/05/29/BuildingHybridSystemswithBoostPython_c.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Thu, 29 May 2008 05:11:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2008/05/29/BuildingHybridSystemswithBoostPython_c.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/51465.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2008/05/29/BuildingHybridSystemswithBoostPython_c.html#Feedback</comments><slash:comments>15</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/51465.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/51465.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Boost.Python是一个开源C++库，它提供了一个简明的IDL式的接口，用于把C++类和函数绑定到Python。借助C++强大的编译时内省能力和最近发展的元编程技术，绑定工作完全用纯C++实现，而没有引入新的语法。 Boost.Python丰富的特性和高级接口，使得完全按混合系统设计软件包成为可能，并让程序员以轻松连贯的方式，同时使用 C++高效的编译时多态，和Python极端便利的运行时多态。&nbsp;&nbsp;<a href='http://www.cppblog.com/jinq0123/archive/2008/05/29/BuildingHybridSystemswithBoostPython_c.html'>阅读全文</a><img src ="http://www.cppblog.com/jinq0123/aggbug/51465.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2008-05-29 13:11 <a href="http://www.cppblog.com/jinq0123/archive/2008/05/29/BuildingHybridSystemswithBoostPython_c.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Python封装的性能研究</title><link>http://www.cppblog.com/jinq0123/archive/2008/05/23/PythonWrapperTools.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Fri, 23 May 2008 03:39:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2008/05/23/PythonWrapperTools.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/50851.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2008/05/23/PythonWrapperTools.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/50851.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/50851.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: SIP generates the fastest wrappers; SWIG is mature and well documented; Boost.Python most elegant integration of C++ and Python&nbsp;&nbsp;<a href='http://www.cppblog.com/jinq0123/archive/2008/05/23/PythonWrapperTools.html'>阅读全文</a><img src ="http://www.cppblog.com/jinq0123/aggbug/50851.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2008-05-23 11:39 <a href="http://www.cppblog.com/jinq0123/archive/2008/05/23/PythonWrapperTools.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>显示wxStaticBitmap的窗口</title><link>http://www.cppblog.com/jinq0123/archive/2008/04/07/FrameWithWxStaticBitmap.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Mon, 07 Apr 2008 03:37:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2008/04/07/FrameWithWxStaticBitmap.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/46412.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2008/04/07/FrameWithWxStaticBitmap.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/46412.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/46412.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 如果不创建wxPanel，只创建wxStaticBitmap，窗口大小变化时，图片显示会不正常，并且指定图片位置和大小无效。wxStaticBitmap的父窗口是fmMain或pnl都可以。 &nbsp;&nbsp;<a href='http://www.cppblog.com/jinq0123/archive/2008/04/07/FrameWithWxStaticBitmap.html'>阅读全文</a><img src ="http://www.cppblog.com/jinq0123/aggbug/46412.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2008-04-07 11:37 <a href="http://www.cppblog.com/jinq0123/archive/2008/04/07/FrameWithWxStaticBitmap.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>XRCed生成的代码分析</title><link>http://www.cppblog.com/jinq0123/archive/2008/03/26/XrcedGeneratedPython.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Wed, 26 Mar 2008 05:23:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2008/03/26/XrcedGeneratedPython.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/45424.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2008/03/26/XrcedGeneratedPython.html#Feedback</comments><slash:comments>9</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/45424.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/45424.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: XRCed是wxPython附带的UI设计器，生成xrc资源文件，也可以输出python代码。本文对XRCed输出的python代码进行分析。&nbsp;&nbsp;<a href='http://www.cppblog.com/jinq0123/archive/2008/03/26/XrcedGeneratedPython.html'>阅读全文</a><img src ="http://www.cppblog.com/jinq0123/aggbug/45424.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2008-03-26 13:23 <a href="http://www.cppblog.com/jinq0123/archive/2008/03/26/XrcedGeneratedPython.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>XRC初步</title><link>http://www.cppblog.com/jinq0123/archive/2008/03/24/XrcPrimary.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Mon, 24 Mar 2008 05:52:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2008/03/24/XrcPrimary.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/45263.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2008/03/24/XrcPrimary.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/45263.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/45263.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: XRC的基本出发点是界面布局和程序逻辑的分离，即将界面布局代码采用XML的方式放在分离的文件之中；在程序中不涉及控件的创建和布局，只需要加载相应的资源并处理事件绑定即可。&nbsp;&nbsp;<a href='http://www.cppblog.com/jinq0123/archive/2008/03/24/XrcPrimary.html'>阅读全文</a><img src ="http://www.cppblog.com/jinq0123/aggbug/45263.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2008-03-24 13:52 <a href="http://www.cppblog.com/jinq0123/archive/2008/03/24/XrcPrimary.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>批量html转text</title><link>http://www.cppblog.com/jinq0123/archive/2008/03/13/PyHtm2txt.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Thu, 13 Mar 2008 03:55:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2008/03/13/PyHtm2txt.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/44354.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2008/03/13/PyHtm2txt.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/44354.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/44354.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 原来的代码是参考“Recipe 12.11. Using MSHTML to Parse XML or HTML”，利用htmlfile提取文本。将当前目录下的所有html文件转换为text文件。jigloo经过对10W+个html文件的测试，得出结论，htmlfile的容错比InternetExplorer.Application要差很多。&nbsp;&nbsp;<a href='http://www.cppblog.com/jinq0123/archive/2008/03/13/PyHtm2txt.html'>阅读全文</a><img src ="http://www.cppblog.com/jinq0123/aggbug/44354.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2008-03-13 11:55 <a href="http://www.cppblog.com/jinq0123/archive/2008/03/13/PyHtm2txt.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Boost.Python构建与测试HOWTO</title><link>http://www.cppblog.com/jinq0123/archive/2008/01/17/BoostPythonBuilding.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Thu, 17 Jan 2008 07:14:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2008/01/17/BoostPythonBuilding.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/41337.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2008/01/17/BoostPythonBuilding.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/41337.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/41337.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 使用Boost.Python不需要“安装Boost”。这里的教程利用了 Boost.Build 项目，它会在需要时自动构建那些二进制库。当然，也可以使用其他的编译系统。所有“我无法编译Boost.Python”的问题， 99%以上是因为试图使用另一种编译系统，而没有先按这个教程做。&nbsp;&nbsp;<a href='http://www.cppblog.com/jinq0123/archive/2008/01/17/BoostPythonBuilding.html'>阅读全文</a><img src ="http://www.cppblog.com/jinq0123/aggbug/41337.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2008-01-17 15:14 <a href="http://www.cppblog.com/jinq0123/archive/2008/01/17/BoostPythonBuilding.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>wxPython中XRC文件i18n示例 </title><link>http://www.cppblog.com/jinq0123/archive/2007/12/17/XrcI18nExample.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Mon, 17 Dec 2007 04:22:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2007/12/17/XrcI18nExample.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/38713.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2007/12/17/XrcI18nExample.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/38713.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/38713.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: wxPython中XRC文件i18n有两种方法，一种是使用多个XRC文件，每个语种一个XRC，另一种是只用一个XRC文件，各个语言使用一个mo翻译文件。本文是按照“wxPython中XRC文件对 i18N的支持”一文的指示，演示使用mo文件对XRC文件进行国际化翻译。  &nbsp;&nbsp;<a href='http://www.cppblog.com/jinq0123/archive/2007/12/17/XrcI18nExample.html'>阅读全文</a><img src ="http://www.cppblog.com/jinq0123/aggbug/38713.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2007-12-17 12:22 <a href="http://www.cppblog.com/jinq0123/archive/2007/12/17/XrcI18nExample.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用list.sort(key)排序</title><link>http://www.cppblog.com/jinq0123/archive/2007/11/21/ListSortByKeyFun.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Wed, 21 Nov 2007 02:36:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2007/11/21/ListSortByKeyFun.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/37066.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2007/11/21/ListSortByKeyFun.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/37066.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/37066.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 一个文件路径链表，需要按文件时间与文件名排序，先按时间排，时间相同按文件名排，代码如下。但是用key函数排序更高效。因为key只对每个项应用一次，然后按key值排序。而cmp函数必须两两比较才行。&nbsp;&nbsp;<a href='http://www.cppblog.com/jinq0123/archive/2007/11/21/ListSortByKeyFun.html'>阅读全文</a><img src ="http://www.cppblog.com/jinq0123/aggbug/37066.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2007-11-21 10:36 <a href="http://www.cppblog.com/jinq0123/archive/2007/11/21/ListSortByKeyFun.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>(Python编程)基本的内嵌技术</title><link>http://www.cppblog.com/jinq0123/archive/2007/09/20/PP3edBasicEmbeddingTechniques.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Thu, 20 Sep 2007 01:44:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2007/09/20/PP3edBasicEmbeddingTechniques.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/32521.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2007/09/20/PP3edBasicEmbeddingTechniques.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/32521.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/32521.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Programming Python, 3rd Edition 翻译。本节列举了几个简短的C程序，它们以一种形式或另一种形式运行Python代码，来演示实际的通用的内嵌技术。&nbsp;&nbsp;<a href='http://www.cppblog.com/jinq0123/archive/2007/09/20/PP3edBasicEmbeddingTechniques.html'>阅读全文</a><img src ="http://www.cppblog.com/jinq0123/aggbug/32521.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2007-09-20 09:44 <a href="http://www.cppblog.com/jinq0123/archive/2007/09/20/PP3edBasicEmbeddingTechniques.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用Python的logging.config</title><link>http://www.cppblog.com/jinq0123/archive/2007/09/03/UsingLoggingConfig.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Mon, 03 Sep 2007 03:35:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2007/09/03/UsingLoggingConfig.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/31449.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2007/09/03/UsingLoggingConfig.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/31449.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/31449.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 使用Python的logging.config.Python的logging模块接口仿log4j，概念上一致，使用上相当方便。利用logging.config.fileConfig()，可以将日志的配置用文件来描述，简化了日志的初始化。例程。&nbsp;&nbsp;<a href='http://www.cppblog.com/jinq0123/archive/2007/09/03/UsingLoggingConfig.html'>阅读全文</a><img src ="http://www.cppblog.com/jinq0123/aggbug/31449.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2007-09-03 11:35 <a href="http://www.cppblog.com/jinq0123/archive/2007/09/03/UsingLoggingConfig.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>(Python编程)Jython：Java的Python</title><link>http://www.cppblog.com/jinq0123/archive/2007/08/08/JythonPythonForJava.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Wed, 08 Aug 2007 10:52:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2007/08/08/JythonPythonForJava.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/29589.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2007/08/08/JythonPythonForJava.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/29589.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/29589.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: Jython（以前叫JPython）是Python编程语言一个完全独特的实现，它让程序员能够在基于Java的应用中使用Python，使 Python成为一个易用的脚本部件。Jython使Python代码看起来像Java代码，因此可以使用各种源自Java世界的技术。Jython也提供了接口，允许Java程序执行Jython代码。Jython的jython程序等同于本书中一直使用的python执行程序。&nbsp;&nbsp;<a href='http://www.cppblog.com/jinq0123/archive/2007/08/08/JythonPythonForJava.html'>阅读全文</a><img src ="http://www.cppblog.com/jinq0123/aggbug/29589.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2007-08-08 18:52 <a href="http://www.cppblog.com/jinq0123/archive/2007/08/08/JythonPythonForJava.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>wxPython中XRC文件对 i18N的支持</title><link>http://www.cppblog.com/jinq0123/archive/2007/07/24/XRCI18N.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Tue, 24 Jul 2007 02:24:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2007/07/24/XRCI18N.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/28684.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2007/07/24/XRCI18N.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/28684.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/28684.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 有关XRC I18N的第一个中文文档。转自[python-chinese]。用XRC生成wxPython的界面,如何实现I18N呢? wxPython的XRC支持包括了对i18N的支持。 &nbsp;&nbsp;<a href='http://www.cppblog.com/jinq0123/archive/2007/07/24/XRCI18N.html'>阅读全文</a><img src ="http://www.cppblog.com/jinq0123/aggbug/28684.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2007-07-24 10:24 <a href="http://www.cppblog.com/jinq0123/archive/2007/07/24/XRCI18N.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Python logging RotatingFileHandler bug</title><link>http://www.cppblog.com/jinq0123/archive/2007/07/23/RotatingFileHandlerBug.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Mon, 23 Jul 2007 03:13:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2007/07/23/RotatingFileHandlerBug.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/28619.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2007/07/23/RotatingFileHandlerBug.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/28619.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/28619.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: doRollover()会因为rename()出错而中途退出，造成日志文件没有打开，并且后继的日志消息都因为日志文件没有打开而失败。我认为正确的处理是丢弃当前一条日志，或者超出日志文件大小限进行附加。如果日志文件打开失败，应该转向标准错误输出，并能在一定时间后重新尝试打开日志文件。<br>&nbsp;&nbsp;<a href='http://www.cppblog.com/jinq0123/archive/2007/07/23/RotatingFileHandlerBug.html'>阅读全文</a><img src ="http://www.cppblog.com/jinq0123/aggbug/28619.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2007-07-23 11:13 <a href="http://www.cppblog.com/jinq0123/archive/2007/07/23/RotatingFileHandlerBug.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Python获取程序所在目录</title><link>http://www.cppblog.com/jinq0123/archive/2007/07/18/GetMainDir.html</link><dc:creator>金庆</dc:creator><author>金庆</author><pubDate>Wed, 18 Jul 2007 07:38:00 GMT</pubDate><guid>http://www.cppblog.com/jinq0123/archive/2007/07/18/GetMainDir.html</guid><wfw:comment>http://www.cppblog.com/jinq0123/comments/28288.html</wfw:comment><comments>http://www.cppblog.com/jinq0123/archive/2007/07/18/GetMainDir.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/jinq0123/comments/commentRss/28288.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/jinq0123/services/trackbacks/28288.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 解决__file__或sys.argv[0]在py2exe下失效的问题。选自pathutils模块。# These functions get us our directory name # Even if py2exe or another freeze tool has been used&nbsp;&nbsp;<a href='http://www.cppblog.com/jinq0123/archive/2007/07/18/GetMainDir.html'>阅读全文</a><img src ="http://www.cppblog.com/jinq0123/aggbug/28288.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/jinq0123/" target="_blank">金庆</a> 2007-07-18 15:38 <a href="http://www.cppblog.com/jinq0123/archive/2007/07/18/GetMainDir.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>