<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>I am LAZY bones ? &#187; 编程相关</title>
	<atom:link href="http://luy.li/category/programme/feed/" rel="self" type="application/rss+xml" />
	<link>http://luy.li</link>
	<description>all linux</description>
	<lastBuildDate>Fri, 21 Oct 2011 03:38:51 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>几个连接数据库用的python模块</title>
		<link>http://luy.li/2010/11/28/python_db/</link>
		<comments>http://luy.li/2010/11/28/python_db/#comments</comments>
		<pubDate>Sun, 28 Nov 2010 04:18:55 +0000</pubDate>
		<dc:creator>bones7456</dc:creator>
				<category><![CDATA[编程相关]]></category>

		<guid isPermaLink="false">http://luy.li/?p=1734</guid>
		<description><![CDATA[工作中，经常会有用python访问各种数据库的需求，比如从oracle读点配置文件或者往mysql写点结果信息之类的。 这里列一下可能用到的各个模块。 sqlite3: 内置模块 用sqlite，有时候确实很方便，我觉得它确实做到了宣称的“零配置”。python自2.5版以来，就内置了对sqlite3的支持，使用也非常简单，按照文档上来： #打开db文件，获得连接 conn = sqlite3.connect&#40;'数据文件名'&#41; #获得游标 c = conn.cursor&#40;&#41; #执行SQL c.execute&#40;'''SQL 片段'''&#41; #如果有对数据的修改操作，那就需要commit一下 conn.commit&#40;&#41; #关闭游标 c.close&#40;&#41; #关闭连接 conn.close&#40;&#41; 另外，关于sqlite在C和bash下的用法，可以参考为以前的文章。 oracle： cx_Oracle 其实，前面先介绍sqlite3，除了它确实是个小数据库以外，还有一个原因：其他数据库在python下的操作，其实基本上和sqlite3的操作是一样的，也就是说，python其实已经几乎统一了数据库的接口。 打开cx_Oracle的文档页面，你会发现其风格也和python文档很像，因为他们都是用 Sphinx 做的。模块的使用方法就更像了，把上面的代码里，获得连接的那行，换成这样： conn = cx_Oracle.connect&#40;'username/password@TNSname'&#41; 就可以了。只要把用户名、密码、TNS组成一个字符串，传进去，就可以得到一个oracle的连接了。 mysql： MySQLdb 和前两个非常类似，连接的时候用以下两个语法之一： conn = MySQLdb.connect&#40;'host', 'username', 'password', 'database'&#41; conn = MySQLdb.connect&#40;host=&#34;host&#34;, user=&#34;username&#34;, passwd=&#34;password&#34;, db=&#34;database&#34;&#41; 接下来，也把它当成sqlite用就好了。 excel： pyExcelerator 好吧，我承认excel不算数据库，只是写在这里充数而已，哈哈。因为偶尔还是要取下别人发来的excel里的数据的。 其实，用pyExcelerator来读取文件也是很简单的： sheets=pyExcelerator.parse_xls&#40;'xxx.xls'&#41; 这样出来以后，sheets就是整个工作薄了，它是工作表组成的list，而一个工作表对应于一个tuple，格式是： [...]]]></description>
			<content:encoded><![CDATA[<p>工作中，经常会有用python访问各种数据库的需求，比如从oracle读点配置文件或者往mysql写点结果信息之类的。<br />
这里列一下可能用到的各个模块。</p>
<p>sqlite3:  <a href="http://docs.python.org/library/sqlite3.html">内置模块</a><br />
用sqlite，有时候确实很方便，我觉得它确实做到了宣称的“零配置”。python自2.5版以来，就内置了对sqlite3的支持，使用也非常简单，按照文档上来：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#打开db文件，获得连接</span>
conn = sqlite3.<span style="color: black;">connect</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'数据文件名'</span><span style="color: black;">&#41;</span>
<span style="color: #808080; font-style: italic;">#获得游标</span>
c = conn.<span style="color: black;">cursor</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #808080; font-style: italic;">#执行SQL</span>
c.<span style="color: black;">execute</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">''</span><span style="color: #483d8b;">'SQL 片段'</span><span style="color: #483d8b;">''</span><span style="color: black;">&#41;</span>
<span style="color: #808080; font-style: italic;">#如果有对数据的修改操作，那就需要commit一下</span>
conn.<span style="color: black;">commit</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #808080; font-style: italic;">#关闭游标</span>
c.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #808080; font-style: italic;">#关闭连接</span>
conn.<span style="color: black;">close</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>另外，关于sqlite在C和bash下的用法，可以参考为以前的<a href="http://luy.li/2009/01/11/sqlite/">文章</a>。</p>
<p>oracle： <a href="http://cx-oracle.sourceforge.net/html/index.html">cx_Oracle</a><br />
其实，前面先介绍sqlite3，除了它确实是个小数据库以外，还有一个原因：其他数据库在python下的操作，其实基本上和sqlite3的操作是一样的，也就是说，python其实已经几乎统一了数据库的接口。<br />
打开cx_Oracle的文档页面，你会发现其风格也和python文档很像，因为他们都是用 Sphinx 做的。模块的使用方法就更像了，把上面的代码里，获得连接的那行，换成这样：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">conn = cx_Oracle.<span style="color: black;">connect</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'username/password@TNSname'</span><span style="color: black;">&#41;</span></pre></div></div>

<p>就可以了。只要把用户名、密码、TNS组成一个字符串，传进去，就可以得到一个oracle的连接了。</p>
<p>mysql： <a href="http://mysql-python.sourceforge.net/MySQLdb.html">MySQLdb</a><br />
和前两个非常类似，连接的时候用以下两个语法之一：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">conn = MySQLdb.<span style="color: black;">connect</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'host'</span>, <span style="color: #483d8b;">'username'</span>, <span style="color: #483d8b;">'password'</span>, <span style="color: #483d8b;">'database'</span><span style="color: black;">&#41;</span>
conn = MySQLdb.<span style="color: black;">connect</span><span style="color: black;">&#40;</span>host=<span style="color: #483d8b;">&quot;host&quot;</span>, <span style="color: #dc143c;">user</span>=<span style="color: #483d8b;">&quot;username&quot;</span>, passwd=<span style="color: #483d8b;">&quot;password&quot;</span>, db=<span style="color: #483d8b;">&quot;database&quot;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>接下来，也把它当成sqlite用就好了。</p>
<p>excel： <a href="http://pyexcelerator.sourceforge.net/">pyExcelerator</a><br />
好吧，我承认excel不算数据库，只是写在这里充数而已，哈哈。因为偶尔还是要取下别人发来的excel里的数据的。<br />
其实，用pyExcelerator来读取文件也是很简单的：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;">sheets=pyExcelerator.<span style="color: black;">parse_xls</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'xxx.xls'</span><span style="color: black;">&#41;</span></pre></div></div>

<p>这样出来以后，sheets就是整个工作薄了，它是工作表组成的list，而一个工作表对应于一个tuple，格式是： <code>('工作表名', 内容)</code>，而内容又是一个dict，key是一个<code>(行数, 列数)</code>的tuple，value才是正在的对应格子的内容。看起来确实比较绕，好在处理excel的应用也不多，将就吧。<br />
另外，其实pyExcelerator还支持写入数据到excel的，如果有把查询结果保存成excel的需求的话，可以试试看，我还是尽量不用这种格式了，哈哈。</p>
]]></content:encoded>
			<wfw:commentRss>http://luy.li/2010/11/28/python_db/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>对老域名用PHP写了个301重定向</title>
		<link>http://luy.li/2010/10/02/php_301/</link>
		<comments>http://luy.li/2010/10/02/php_301/#comments</comments>
		<pubDate>Sat, 02 Oct 2010 12:34:36 +0000</pubDate>
		<dc:creator>bones7456</dc:creator>
				<category><![CDATA[编程相关]]></category>

		<guid isPermaLink="false">http://luy.li/?p=1717</guid>
		<description><![CDATA[之前，这里的域名一直都是 li2z.cn ，但是，被CNNIC逼得走投无路以后，我终于把域名换成 luy.li 了。其实准确的说，不是“换”，是加了一个域名，并射成默认了而已，因此用 li2z.cn 还是可以访问的，甚至连301都没有做，之前我的做法只是把两个域名的后台路径指向同一个了而已（题外话：由于两个站的内容完全一致，所以被google惩罚了，li2z.cn 的PR瞬间就变成0了，所以在意PR的站长千万别这么干哦~）。 现在，时间也过去这么久了，大多数的流量已经是新域名下的了，但是老域名的流量也还有不少，于是我就想能不能在不影响访问的同时，统计一下老域名的每次http请求的来路。 方法自然是把所有request用301重定向到 luy.li 的对应地址，然后在日志里记录refer了（不明白301和refer的请自行google基础知识）。 这个用我三脚猫的php都很容易搞定，就几行代码，index.php如下： &#60;?php header&#40;&#34;HTTP/1.1 301 Moved Permanently&#34;&#41;; header&#40;&#34;Location: http://luy.li&#34;.$_SERVER&#91;'REQUEST_URI'&#93;&#41;; date_default_timezone_set&#40;'Etc/GMT-8'&#41;; $msg = date&#40;'Y-m-d H:i:s'&#41;.' '.$_SERVER&#91;'HTTP_REFERER'&#93;.' '.$_SERVER&#91;'REQUEST_URI'&#93;.&#34;\n&#34;; file_put_contents&#40;'log.txt',$msg,FILE_APPEND&#41;; ?&#62; 然后，建个 .htaccess 把域名下的所有请求都指向 index.php: &#60;IfModule mod_rewrite.c&#62; RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . index.php [L] &#60;/IfModule&#62; 测试一下，对get请求，可以完整地转到新的域名了： $ curl -v "http://li2z.cn/abc?xxx=yyy" * About [...]]]></description>
			<content:encoded><![CDATA[<p>之前，这里的域名一直都是 <code>li2z.cn</code> ，但是，被CNNIC逼得走投无路以后，我终于把<a href="http://luy.li/2010/06/16/luyli/">域名换成</a> <code>luy.li</code> 了。其实准确的说，不是“换”，是加了一个域名，并射成默认了而已，因此用 li2z.cn 还是可以访问的，甚至连301都没有做，之前我的做法只是把两个域名的后台路径指向同一个了而已（题外话：由于两个站的内容完全一致，所以被google惩罚了，li2z.cn 的PR瞬间就变成0了，所以在意PR的站长千万别这么干哦~）。<br />
现在，时间也过去这么久了，大多数的流量已经是新域名下的了，但是老域名的流量也还有不少，于是我就想能不能在不影响访问的同时，统计一下老域名的每次http请求的来路。<br />
方法自然是把所有request用301重定向到 luy.li 的对应地址，然后在日志里记录refer了（不明白301和refer的请自行google基础知识）。<br />
这个用我三脚猫的php都很容易搞定，就几行代码，index.php如下：</p>

<div class="wp_syntax"><div class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #990000;">header</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;HTTP/1.1 301 Moved Permanently&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">header</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Location: http://luy.li&quot;</span><span style="color: #339933;">.</span><span style="color: #000088;">$_SERVER</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'REQUEST_URI'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">date_default_timezone_set</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Etc/GMT-8'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$msg</span> <span style="color: #339933;">=</span> <span style="color: #990000;">date</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'Y-m-d H:i:s'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">' '</span><span style="color: #339933;">.</span><span style="color: #000088;">$_SERVER</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'HTTP_REFERER'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">' '</span><span style="color: #339933;">.</span><span style="color: #000088;">$_SERVER</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'REQUEST_URI'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">.</span><span style="color: #0000ff;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">file_put_contents</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'log.txt'</span><span style="color: #339933;">,</span><span style="color: #000088;">$msg</span><span style="color: #339933;">,</span>FILE_APPEND<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span></pre></div></div>

<p>然后，建个 .htaccess 把域名下的所有请求都指向 index.php:</p>

<div class="wp_syntax"><div class="code"><pre class="txt" style="font-family:monospace;">&lt;IfModule mod_rewrite.c&gt;
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php [L]
&lt;/IfModule&gt;</pre></div></div>

<p>测试一下，对get请求，可以完整地转到新的域名了：</p>
<p>$ <code>curl -v "http://li2z.cn/abc?xxx=yyy"</code><br />
* About to connect() to li2z.cn port 80 (#0)<br />
*   Trying 66.147.240.158&#8230; connected<br />
* Connected to li2z.cn (66.147.240.158) port 80 (#0)<br />
> GET /abc?xxx=yyy HTTP/1.1<br />
> User-Agent: curl/7.21.1 (i686-pc-linux-gnu) libcurl/7.21.1 GnuTLS/2.10.2 zlib/1.2.5<br />
> Host: li2z.cn<br />
> Accept: */*<br />
><br />
< HTTP/1.1 301 Moved Permanently<br />
< Date: Sat, 02 Oct 2010 12:05:53 GMT<br />
< Server: Apache<br />
< X-Powered-By: PHP/5.2.14<br />
< Location: <code>http://luy.li/abc?xxx=yyy</code><br />
< Cache-Control: max-age=1<br />
< Expires: Sat, 02 Oct 2010 12:05:54 GMT<br />
< Vary: Accept-Encoding<br />
< Content-Length: 0<br />
< Content-Type: text/html<br />
<<br />
* Connection #0 to host li2z.cn left intact<br />
* Closing connection #0<br />
然后在后台目录里会生成一个 log.txt ，里面会有所有访问的时间、refer和uri，这样日后就可以方便地查出老域名的所有来路和受访页面了，最重要的是，由于有301，还不会对正常访问造成影响哦~</p>
]]></content:encoded>
			<wfw:commentRss>http://luy.li/2010/10/02/php_301/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>python编程细节──遍历dict的两种方法比较</title>
		<link>http://luy.li/2010/09/17/python_traversal_dict/</link>
		<comments>http://luy.li/2010/09/17/python_traversal_dict/#comments</comments>
		<pubDate>Fri, 17 Sep 2010 13:44:49 +0000</pubDate>
		<dc:creator>bones7456</dc:creator>
				<category><![CDATA[编程相关]]></category>

		<guid isPermaLink="false">http://luy.li/?p=1704</guid>
		<description><![CDATA[python以其优美的语法和方便的内置数据结构，赢得了不少程序员的亲睐。 其中有个很有用的数据结构，就是字典（dict），使用非常简单。说到遍历一个dict结构，我想大多数人都会想到 for key in dictobj 的方法，确实这个方法在大多数情况下都是适用的。但是并不是完全安全，请看下面这个例子： #这里初始化一个dict &#62;&#62;&#62; d = &#123;'a':1, 'b':0, 'c':1, 'd':0&#125; #本意是遍历dict，发现元素的值是0的话，就删掉 &#62;&#62;&#62; for k in d: ... if d&#91;k&#93; == 0: ... del&#40;d&#91;k&#93;&#41; ... Traceback &#40;most recent call last&#41;: File &#34;&#60;stdin&#62;&#34;, line 1, in &#60;module&#62; RuntimeError: dictionary changed size during iteration #结果抛出异常了，两个0的元素，也只删掉一个。 &#62;&#62;&#62; d &#123;'a': 1, 'c': 1, 'd': 0&#125; [...]]]></description>
			<content:encoded><![CDATA[<p>python以其优美的语法和方便的内置数据结构，赢得了不少程序员的亲睐。<br />
其中有个很有用的数据结构，就是字典（dict），使用非常简单。说到遍历一个dict结构，我想大多数人都会想到 <code>for key in dictobj</code> 的方法，确实这个方法在大多数情况下都是适用的。但是并不是完全安全，请看下面这个例子：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#这里初始化一个dict</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> d = <span style="color: black;">&#123;</span><span style="color: #483d8b;">'a'</span>:<span style="color: #ff4500;">1</span>, <span style="color: #483d8b;">'b'</span>:<span style="color: #ff4500;">0</span>, <span style="color: #483d8b;">'c'</span>:<span style="color: #ff4500;">1</span>, <span style="color: #483d8b;">'d'</span>:<span style="color: #ff4500;">0</span><span style="color: black;">&#125;</span>
<span style="color: #808080; font-style: italic;">#本意是遍历dict，发现元素的值是0的话，就删掉</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">for</span> k <span style="color: #ff7700;font-weight:bold;">in</span> d:
...   <span style="color: #ff7700;font-weight:bold;">if</span> d<span style="color: black;">&#91;</span>k<span style="color: black;">&#93;</span> == <span style="color: #ff4500;">0</span>:
...     <span style="color: #ff7700;font-weight:bold;">del</span><span style="color: black;">&#40;</span>d<span style="color: black;">&#91;</span>k<span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
... 
<span style="color: black;">Traceback</span> <span style="color: black;">&#40;</span>most recent call last<span style="color: black;">&#41;</span>:
  File <span style="color: #483d8b;">&quot;&lt;stdin&gt;&quot;</span>, line <span style="color: #ff4500;">1</span>, <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #66cc66;">&lt;</span>module<span style="color: #66cc66;">&gt;</span>
<span style="color: #008000;">RuntimeError</span>: dictionary changed size during iteration
<span style="color: #808080; font-style: italic;">#结果抛出异常了，两个0的元素，也只删掉一个。</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> d
<span style="color: black;">&#123;</span><span style="color: #483d8b;">'a'</span>: <span style="color: #ff4500;">1</span>, <span style="color: #483d8b;">'c'</span>: <span style="color: #ff4500;">1</span>, <span style="color: #483d8b;">'d'</span>: <span style="color: #ff4500;">0</span><span style="color: black;">&#125;</span>
&nbsp;
<span style="color: #66cc66;">&gt;&gt;&gt;</span> d = <span style="color: black;">&#123;</span><span style="color: #483d8b;">'a'</span>:<span style="color: #ff4500;">1</span>, <span style="color: #483d8b;">'b'</span>:<span style="color: #ff4500;">0</span>, <span style="color: #483d8b;">'c'</span>:<span style="color: #ff4500;">1</span>, <span style="color: #483d8b;">'d'</span>:<span style="color: #ff4500;">0</span><span style="color: black;">&#125;</span>
<span style="color: #808080; font-style: italic;">#d.keys() 是一个下标的数组</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> d.<span style="color: black;">keys</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: black;">&#91;</span><span style="color: #483d8b;">'a'</span>, <span style="color: #483d8b;">'c'</span>, <span style="color: #483d8b;">'b'</span>, <span style="color: #483d8b;">'d'</span><span style="color: black;">&#93;</span>
<span style="color: #808080; font-style: italic;">#这样遍历，就没问题了，因为其实其实这里遍历的是d.keys()这个list常量。</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> <span style="color: #ff7700;font-weight:bold;">for</span> k <span style="color: #ff7700;font-weight:bold;">in</span> d.<span style="color: black;">keys</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
...   <span style="color: #ff7700;font-weight:bold;">if</span> d<span style="color: black;">&#91;</span>k<span style="color: black;">&#93;</span> == <span style="color: #ff4500;">0</span>:
...     <span style="color: #ff7700;font-weight:bold;">del</span><span style="color: black;">&#40;</span>d<span style="color: black;">&#91;</span>k<span style="color: black;">&#93;</span><span style="color: black;">&#41;</span>
... 
<span style="color: #66cc66;">&gt;&gt;&gt;</span> d
<span style="color: black;">&#123;</span><span style="color: #483d8b;">'a'</span>: <span style="color: #ff4500;">1</span>, <span style="color: #483d8b;">'c'</span>: <span style="color: #ff4500;">1</span><span style="color: black;">&#125;</span>
<span style="color: #808080; font-style: italic;">#结果也是对的</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span></pre></div></div>

<p>其实，这个例子是我简化过的，我是在一个多线程的程序里发现这个问题的，所以，我的建议是：遍历dict的时候，养成使用 <code>for k in d.keys()</code> 的习惯。<br />
不过，如果是多线程的话，这样就绝对安全吗？也不见得：当两个线程都取完d.keys()以后，如果两个线程都去删同一个key的话，先删的会成功，后删的那个肯定会报 KeyError ，这个看来只能通过其他方式来保证了。</p>
]]></content:encoded>
			<wfw:commentRss>http://luy.li/2010/09/17/python_traversal_dict/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>设置python的stdout为无缓存模式</title>
		<link>http://luy.li/2010/08/29/pythonunbuffered/</link>
		<comments>http://luy.li/2010/08/29/pythonunbuffered/#comments</comments>
		<pubDate>Sun, 29 Aug 2010 13:52:01 +0000</pubDate>
		<dc:creator>bones7456</dc:creator>
				<category><![CDATA[编程相关]]></category>

		<guid isPermaLink="false">http://luy.li/?p=1686</guid>
		<description><![CDATA[考虑以下python程序： #!/usr/bin/env python &#160; import sys &#160; sys.stdout.write&#40;&#34;stdout1 &#34;&#41; sys.stderr.write&#40;&#34;stderr1 &#34;&#41; sys.stdout.write&#40;&#34;stdout2 &#34;&#41; sys.stderr.write&#40;&#34;stderr2 &#34;&#41; 其中的sys.stdout.write也可以换成print。 运行这程序，你觉得会输出什么？试验一下，就会发现，其实输出并不是 stdout1 stderr1 stdout2 stderr2 而是： stderr1 stderr2 stdout1 stdout2 究其原因，是因为缓存：虽然stderr和stdout默认都是指向屏幕的，但是stderr是无缓存的，程序往stderr输出一个字符，就会在屏幕上显示一个；而stdout是有缓存的，只有遇到换行或者积累到一定的大小，才会显示出来。这就是为什么上面的会显示两个stderr的原因了。 然而，有时候，你可能还是希望stdout的行为和stderr一样，能不能实现呢？当然是可以的，而且对于python，实现起来还特别方便，以下是两个方法： python -u stderr_stdout.py PYTHONUNBUFFERED=1 python stderr_stdout.py 第一种方法是给python指定 -u 参数，第二种方法是在python运行时，指定 PYTHONUNBUFFERED 环境变量，这两种方法其实是等效的。 当然，也可以在程序的第一行指定 #!/usr/bin/python -u 然后程序加可执行权限来运行，或者把 export PYTHONUNBUFFERED=1 写到 .bashrc 里去。]]></description>
			<content:encoded><![CDATA[<p>考虑以下python程序：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #808080; font-style: italic;">#!/usr/bin/env python</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">sys</span>
&nbsp;
<span style="color: #dc143c;">sys</span>.<span style="color: black;">stdout</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;stdout1 &quot;</span><span style="color: black;">&#41;</span>
<span style="color: #dc143c;">sys</span>.<span style="color: black;">stderr</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;stderr1 &quot;</span><span style="color: black;">&#41;</span>
<span style="color: #dc143c;">sys</span>.<span style="color: black;">stdout</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;stdout2 &quot;</span><span style="color: black;">&#41;</span>
<span style="color: #dc143c;">sys</span>.<span style="color: black;">stderr</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;stderr2 &quot;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>其中的sys.stdout.write也可以换成print。<br />
运行这程序，你觉得会输出什么？试验一下，就会发现，其实输出并不是</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">stdout1 stderr1  stdout2 stderr2</pre></div></div>

<p>而是：</p>

<div class="wp_syntax"><div class="code"><pre class="text" style="font-family:monospace;">stderr1 stderr2 stdout1  stdout2</pre></div></div>

<p>究其原因，是因为缓存：虽然stderr和stdout默认都是指向屏幕的，但是stderr是无缓存的，程序往stderr输出一个字符，就会在屏幕上显示一个；而stdout是有缓存的，只有遇到换行或者积累到一定的大小，才会显示出来。这就是为什么上面的会显示两个stderr的原因了。<br />
然而，有时候，你可能还是希望stdout的行为和stderr一样，能不能实现呢？当然是可以的，而且对于python，实现起来还特别方便，以下是两个方法：</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">python <span style="color: #660033;">-u</span> stderr_stdout.py</pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #007800;">PYTHONUNBUFFERED</span>=<span style="color: #000000;">1</span> python stderr_stdout.py</pre></div></div>

<p>第一种方法是给python指定 -u 参数，第二种方法是在python运行时，指定 <code>PYTHONUNBUFFERED</code> 环境变量，这两种方法其实是等效的。<br />
当然，也可以在程序的第一行指定 #!/usr/bin/python -u 然后程序加可执行权限来运行，或者把 export PYTHONUNBUFFERED=1 写到 .bashrc 里去。</p>
]]></content:encoded>
			<wfw:commentRss>http://luy.li/2010/08/29/pythonunbuffered/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>为什么python里要 if __name__ == &#8216;__main__&#8217;:</title>
		<link>http://luy.li/2010/05/31/python__name__main__/</link>
		<comments>http://luy.li/2010/05/31/python__name__main__/#comments</comments>
		<pubDate>Mon, 31 May 2010 10:52:14 +0000</pubDate>
		<dc:creator>bones7456</dc:creator>
				<category><![CDATA[编程相关]]></category>

		<guid isPermaLink="false">http://li2z.cn/?p=1581</guid>
		<description><![CDATA[尽管python允许你像shell脚本一样，把大段的代码堆积着写，但是，很多python入门的书，都会建议你把代码写成一个函数，然后在最后面统一调用，例如这样： def main&#40;&#41;: #具体代码 &#160; if __name__ == '__main__': main&#40;&#41; 很多文章都会说这个是由于代码风格之类的原因，但是其实，不这样写，有时候也是会直接导致出错的。 举个例子，打开《A Byte of Python》的类变量那节，可以这里看在线版本，然后把中间的那示例代码复制下来，运行，可以看到，确实能得到预期正确的结果。 但是，现在把那代码里的所有“swaroop”换成“xxx1”，再把所有“kalam”换成“yyy1”，再运行，就会在程序运行的最后时刻，得到这么一个奇怪的错误（Python 2.6.5下实验）： Exception AttributeError: "'NoneType' object has no attribute 'population'" in ignored 也就是说，换了个变量名，程序就出错了。。。 究其原因，应该是python在最后析构所有类和对象的时候，并没有处理这些对象之间的依赖关系，而是根据变量名来决定某种顺序操作了。从而导致Person类本身，先于yyy2被干掉了，所以在解构yyy2的时候，执行它的__del__()方法，却发现父类都已经没有了~~ 这应该确实算是python解析器的bug，但是，如果那把这个例子里的所有class Person以外的代码，写到一个main()函数里，再通过上述方法调用的话，就不会发生这种错误了。 所以，大家最好还是别太在意多几行代码，养成这个好习惯吧。 要深究此错误的原因，可以看官方文档里的描述，并在这里讨论。]]></description>
			<content:encoded><![CDATA[<p>尽管python允许你像shell脚本一样，把大段的代码堆积着写，但是，很多python入门的书，都会建议你把代码写成一个函数，然后在最后面统一调用，例如这样：</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #ff7700;font-weight:bold;">def</span> main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
    <span style="color: #808080; font-style: italic;">#具体代码</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">if</span> __name__ == <span style="color: #483d8b;">'__main__'</span>:
    main<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre></div></div>

<p>很多文章都会说这个是由于代码风格之类的原因，但是其实，不这样写，有时候也是会直接导致出错的。<br />
举个例子，打开《A Byte of Python》的类变量那节，可以<a href="http://www.ibiblio.org/swaroopch/byteofpython/read/class-and-object-vars.html">这里看在线版本</a>，然后把中间的那示例代码复制下来，运行，可以看到，确实能得到预期正确的结果。<br />
但是，现在把那代码里的所有“swaroop”换成“xxx1”，再把所有“kalam”换成“yyy1”，再运行，就会在程序运行的最后时刻，得到这么一个奇怪的错误（Python 2.6.5下实验）：<br />
<code>Exception AttributeError: "'NoneType' object has no attribute 'population'" in <bound method Person.__del__ of <__main__.Person instance at 0xb689090c>> ignored</code><br />
也就是说，换了个变量名，程序就出错了。。。<br />
究其原因，应该是python在最后析构所有类和对象的时候，并没有处理这些对象之间的依赖关系，而是根据变量名来决定某种顺序操作了。从而导致<code>Person</code>类本身，先于<code>yyy2</code>被干掉了，所以在解构<code>yyy2</code>的时候，执行它的<code>__del__()</code>方法，却发现父类都已经没有了~~<br />
这应该确实算是python解析器的bug，但是，如果那把这个例子里的所有class Person以外的代码，写到一个<code>main()</code>函数里，再通过上述方法调用的话，就不会发生这种错误了。<br />
所以，大家最好还是别太在意多几行代码，养成这个好习惯吧。</p>
<p>要深究此错误的原因，可以看官方文档里的<a href="http://docs.python.org/c-api/init.html#Py_Finalize">描述</a>，并在<a href="http://groups.google.com/group/python-cn/browse_thread/thread/31df4e6076782599">这里</a>讨论。</p>
]]></content:encoded>
			<wfw:commentRss>http://luy.li/2010/05/31/python__name__main__/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
	</channel>
</rss>

