轩痕的竹林

Happy coding

python中的陷阱(1)

d = {}  与  d.clear() 的区别

在工作中我想实现一个这样的效果:

在循环中把一个字典的不同状态值加入到list里面去,可是这个结果一致很异常。

看下面的问题代码:

In [1]: l = []

In [2]: p = {}

In [3]: for i in xrange(5):
   ...:     p.clear()
   ...:     p[str(i)] = i
   ...:     print p
   ...:     l.append(p)
   ...:     print l
   ...:     
   ...:     
{'0': 0}
[{'0': 0}]
{'1': 1}
[{'1': 1}, {'1': 1}]
{'2': 2}
[{'2': 2}, {'2': 2}, {'2': 2}]
{'3': 3}
[{'3': 3}, {'3': 3}, {'3': 3}, {'3': 3}]
{'4': 4}
[{'4': 4}, {'4': 4}, {'4': 4}, {'4': 4}, {'4': 4}]

 

 

发现了吗? l.append操作每次只是把对象的地址放入了队列里面进行保存,而p.clear() 这个函数不会创建新的字典,只是把原来p = {}创建的变量内容给清空了。我们每次放入l之中的都是p = {}创建的变量地址,所以导致l 里面的结果跟所想想的完全不一致。

 

作为对比,下面才是我们想要的结果。

In [6]: l = []

In [7]: for i in xrange(5):
    p = {}
    p[str(i)] = i
    print p
    l.append(p)
    print l
   ....:    
   ....:    
{'0': 0}
[{'0': 0}]
{'1': 1}
[{'0': 0}, {'1': 1}]
{'2': 2}
[{'0': 0}, {'1': 1}, {'2': 2}]
{'3': 3}
[{'0': 0}, {'1': 1}, {'2': 2}, {'3': 3}]
{'4': 4}
[{'0': 0}, {'1': 1}, {'2': 2}, {'3': 3}, {'4': 4}]

 

我们必须在for循环的开始就通过p = {} 来创建一个新的变量,跟之前的那个变量地址完全不能一样。这样才能让不同的字典加入到我们的队列里面

 

上面是我的猜测,是真的这样吗? 我们验证一下


In [20]: l = []

In [21]: for i in xrange(5):
    p = {}
    p[str(i)] = i
    print p
    l.append(p)
    print l
    p.clear()
   ....:     
   ....:     
{'0': 0}
[{'0': 0}]
{'1': 1}
[{}, {'1': 1}]
{'2': 2}
[{}, {}, {'2': 2}]
{'3': 3}
[{}, {}, {}, {'3': 3}]
{'4': 4}
[{}, {}, {}, {}, {'4': 4}]



看到了吗? clear()成员函数清空了p = {}产生的变量的内容,而列表里面仍然保存着这个空变量的地址,列表自己当然不知道了。。 所以很遗憾。。 我们什么都没得到。。 我应该在最后再打印下l , 不过其实已经没有必要了, 不是吗?

仓央嘉措诗一首

 

那一刻 
我升起风马 
不为乞福 
只为守候你的到来 
那一日 
垒起玛尼堆 
不为修德 
只为投下心湖的石子 
那一月 
我摇动所有的经筒 
不为超度 
只为触摸你的指尖 
那一年 
磕长头在山路 
为觐见 
只为贴着你的温暖 
这一世

转山 
不为轮回 
只为途中与你相见 
.

那一天 
闭目在经殿香雾中 
蓦然听见你颂经中的真言 
那一月 
我摇动所有的转经筒 
不为超度 
只为触摸你的指尖 
那一年 
磕长头匍匐在山路 
不为觐见 
只为贴着你的温暖 
那一世 
转山转水转佛塔啊 
不为修来生 
只为途中与你相见 
.
.

那一夜 
我听了一宿梵唱 
不为参悟 
只为寻你的一丝气息
那一月 
我转过所有经筒 
不为超度 
只为触摸你的指纹 
那一年 
我磕长头拥抱尘埃 
不为朝佛 
只为贴着你的温暖 
那一世 
我翻遍十万大山 
不为修来世 
只为路中能与你相遇

.

 

有一个藏族诗人叫仓央嘉措。仓央嘉措,意为“梵音海”,他是第六世达赖喇嘛,生于1683年,一个农民的儿子。


多年以后,人们忘记了他的达赖身份,因为他的情诗已经在很多人口中交相传诵。他的传奇,他的故事让无数人为之着迷,他的诗歌犹如是青藏高原又一颗明珠,照亮了每个有着美好梦想者的心堂。

.
相传仓央嘉措在入选达赖前,在家乡有一位美貌聪明的意中人,他们终日相伴,耕作放牧,青梅竹马,恩爱至深。仓央嘉措进入布达故宫后,他厌倦深宫内单调而刻板的黄教领袖生活,时时怀念着民间多彩的习俗,思恋着美丽的情人。他便经常微服夜出,与情人相会,追求浪漫的爱情生活。有一天下大雪,清早起来,铁棒喇嘛发现雪地上有人外出的脚印,便顺着脚印寻觅,最后脚印进入了仓央嘉措的寝宫。随后铁棒喇嘛用严刑处置了仓央嘉措的贴身喇嘛,还派人把他的情人处死,采取严厉措施,把仓央嘉措关闭起来。悲痛欲绝仓央嘉措便把佛深深埋进了心底,拿起笔开始了他的诗歌创作。 

python处理url

我现在有一些这样的数据,用来生成url,以提供给爬虫进行爬取。

Venture Capital
Banking (excl. Investment Banking)
Washington, D.C.
Nightlife in Washington, DC
Amazon $175mm Investment in LivingSocial (December 2010)

Twitter's Future

Florian Leibert / Noirin Shirley Incident

这些数据最终要以 - 进行连接,来生成地址。

上代码:

#ipython 下执行
import re
In [41]: path = re.sub("[?@ =#().&]", "-", "Banking (excl. Investment Banking)") 
In [42]: path
Out[42]: 'Banking--excl--Investment-Banking-'

In [43]: path1 = re.sub("-+","-",path)

In [44]: path1
Out[44]: 'Banking-excl-Investment-Banking-'

In [45]: path1.rstrip('-')
Out[45]: 'Banking-excl-Investment-Banking'


如果有一些新发现的奇怪字符,在

re.sub("[?@ =#().&]", "-", "Banking (excl. Investment Banking)") 

那一堆符号里面加上新符号就是了。
 

 

mechanize加载firefox3的cookies.sqlite文件

刚刚搞成功,尝试了好久,谁让mechanize这个东西的文档实在糟糕呢。。

mechanize的文档说它不支持ff3的cookies.sqlite文件,其实它是支持了的,这种情况确实让人郁闷。

我说说我的步骤。

首先看代码吧:

import mechanize

#根据自己的路径情况找到这个文件
db_path = '/home/xuanhen/.mozilla/firefox/lq6mrvtv.default/cookies.sqlite'  

#这个成员函数其实是有问题的,需要自己修改下,见后文
cookiejar = mechanize.Firefox3CookieJar(db_path) 

br = mechanize.Browser()
# 设置是否遵守爬虫协议,这里是不遵守,否则这个站不让爬
br.set_handle_robots(False)

#装载cookiejar,它会自动对后面访问的网站应用合适的cookie
br.set_cookiejar(cookiejar) 

url = "http://www.quora.com/"
response = br.open(url)  
s = response.read()

#html文件不好判断是否登录成功,就写成文本,然后通过浏览器打开来判断
f = open('./xx.html','w') 
f.write(s)
f.close()

注意:

1. mechanize.Firefox3CookieJar() 这个函数在加载cookie文件的时候会报编码错误,打开/usr/local/lib/python2.6/dist-packages/mechanize-0.2.4-py2.6.egg/mechanize/_firefox3cookiejar.py 文件(你的可不一定在这个位置),在第63行插入

self._conn.text_factory=lambda x: unicode(x, "utf-8", "ignore")

结果如下:

 59     def connect(self):
 60         import sqlite3  # not available in Python 2.4 stdlib
 61         self._conn = sqlite3.connect(self.filename)
 62         self._conn.isolation_level = "DEFERRED"
 63         self._conn.text_factory=lambda x: unicode(x, "utf-8", "ignore")
 64         self._create_table_if_necessary()

 

2. 如果这个函数没有报编码错误,而是key错误之类的,我不知道如何解决,我也遇到了,我猜测是由于有的cookie格式有问题,所以我就删除了cookies.sqlite文件,然后重新启动火狐,访问你要模拟登录的网站,让火狐把cookie给记录到它的sqlite数据库里面就可以了。

 

博客开通拉

    以前不会写网站的时候搞过wordpress的独立博客,后来没有坚持写下来。现在能用django写网站了,但是又懒得自己折腾域名什么的,整天配服务器,也懒得给自己配一个。。。干脆就寄居在此。is-programmer,哈哈,我喜欢这个域名。