二月 2, 2010
» [tips] python2與python 3的list comprehensions之差異

剛好看到這篇
http://yz.mit.edu/wp/2010/01/14/bitten-by-python-scoping/
想起之前也有遇到類似的問題~

其實主要就是python2的list comprehensions有個副作用,
就是會重設scope內的變數, 比如以下這個程式

def t1(): 
x=5
[0 for x in [1,2,3]]
print x

t1()

3

這邊的x會被重設為3, 有點像是殘餘的loop變數的感覺~
有些人會玩弄這個副作用來達到一些不想讓人看懂的lambda技巧就是了:P

但相對來說後來引進的generator語法就沒有這個問題, 所以這個問題其實也可以使用list(x for x in [1,2,3])這個方法來解決.
def ts2():
x=5
list(x for x in [1,2,3])
print x

ts2()

5

另外也可以置換變數比如改成使用a來取代x(當然a是會被assigned).

當然還有另外一個方法則是使用python 3, 就完全沒有這個問題了 :D

三月 17, 2009
» [tips] crc32 in python

python 2.X的crc32實作上跟一般的C實作上在整數有號無號的處理上略有不同, 所以使用python 2.X與一般C實作算出的crc32(如sfv)比對時,通常需要特別的方法,

這邊列出一個透過zlib.crc32快速得到所需要結果的方法:

import zlib

def crc32(st):
crc = zlib.crc32(st)
if crc > 0:
return "%x" % (crc)
else:
return "%x" % (~crc ^ 0xffffffff)

ex1 = "12345"
ex2 = "1kcaseztsa12345azy"

print "%x" % zlib.crc32(ex1)
print crc32(ex1)
print "%x" % zlib.crc32(ex2)
print crc32(ex2)


或如果你有ctypes的話:
import zlib
import ctypes

def crc32_c(st):
return "%x" % ctypes.c_uint32(zlib.crc32(st)).value

ex1 = "12345"
ex2 = "1kcaseztsa12345azy"

print "%x" % zlib.crc32(ex1)
print crc32_c(ex1)
print "%x" % zlib.crc32(ex2)
print crc32_c(ex2)



註: python 3.0以上沒有這個問題.

六月 19, 2007
» [link] Py3K status.

Python 3000 Status Update 來自BDFL (GvR) 的消息, 說明目前python 3.0的發展狀況.

python 3.0的第一個alpha測試版本將延至今年八月底釋出. (還有兩個月!)
所以預定3.0的最終釋出版本也順延至2008年第二季後.

恩, 照這個估算2009才是python3.0正式的開始.
還有一年半的時間可以假裝這世界上沒有python 3.0 ;)

六月 14, 2007
» PEP 3104 Access to Names in Outer Scopes -- or the ture closures for py3k

http://www.python.org/dev/peps/pep-3104/

python 2.1以前, python是沿用C對scope的思維,
只有很簡單的global跟local的scope概念.
(and builtin)

python 2.1之後引進nested scoping,的確帶來了不少彈性,
不過比起一些更為彈性的語言來說, 對於scoping的控制
仍然無法稱作完善.
而PEP 3104引進了nonlocal這個關鍵字後,
總算讓在python使用closure顯得自然.

目前2.X的狀況:

 
Python 2.4.4 (#2, Apr 5 2007, 20:11:18)
[GCC 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> def x():
... t=9
... def y():
... print t
... t = 10
... print t
... return y
...
>>> z = x()
>>> z()
Traceback (most recent call last):
File "", line 1, in ?
File "", line 4, in y
UnboundLocalError: local variable 't' referenced before assignment


雖然 我們的用意是要讓t被enclosed, 但是卻沒辦法修改t.
注意到為什麼了吗?
由於在scope範圍內有了對t的assignment,
因此python會implicit的認為t是個local變數..
啊 可是我的第一個print t敘述裡的t要的不是被rebind過的t啊~~!

ㄟ.... 老師沒告訴你吗?
"Explicit is better than implicit." :D
所以py3k引入了nonlocal這個keyword,
以往只能用各種hack來解決的這個問題,
(最常用的一種是傳入list[0]),
會相對的使得closure的運用顯得不夠直覺.
在py3k底下則可以寫成這樣:
(現在print 改成 function ,,要括號,, 真容易打錯 :P )


Python 3.0x (p3yk:55958, Jun 13 2007, 18:39:18)
[GCC 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> def x():
... t=9
... def y():
... nonlocal t
... print(t)
... t=10
... print(t)
... return y
...
>>> z = x()
>>> z()
9
10


加入了nonlocal這個declare之後,
是不是比以前清楚的多呢 :)

biggo.com.tw

A Django site.