[Python] 自己編譯 Wide python 解決 Narrow python 的問題

[Python] 自己編譯 Wide python 解決 Narrow python 的問題

其實也是網友在 使用 mechanize 自動登入網站 留言裡,

提到了遇到了奇怪的錯誤訊息,

才知道 python 2.x 有所謂的 narrow python 的問題…

 

不懂 narrow python 的人可以參考一下:

  – Narrow Python

  – ValueError: unichr() arg not in range(0x10000) (narrow Python build)

 

基本上 python 2.x 預設編譯狀態就是 narrow python,

代表一個 unicode 字元是用兩個 byte 來表示的 (也就是 ucs2)~

這平常沒什麼問題,但是如果用到超過 0xFFFF 的 Unicode 字元時,

就會出事了:

>>> unichr(0x10000)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: unichr() arg not in range(0x10000) (narrow Python build)

 

Python 3.x 全面支援 Unicode,所以連 unichr() 這個函式都沒了,

chr() 就可以處理這種 Unicode 字元了~

可是如果我就是要用 Pytho 2.x 怎麼辦呢?

只好自己重新編譯 Python 囉~ 

 

1. 下載 Python 原始檔

我這邊用的是 python 2.6.8,也可以再去官網找更新的 2.x 版本:

wget http://www.python.org/ftp/python/2.6.8/Python-2.6.8.tgz
tar zxvf Python-2.6.8.tgz
cd Python-2.6.8

 

2. 設定 Python 組態

在執行 configure 時要注意加上 –enable-unicode=ucs4 才能編譯出 wide python,

我這邊還加上了 –with-threads 來支援 threading 的處理:

./configure --with-threads --enable-unicode=ucs4

 

如果不想把 python 裝到系統目錄裡 /usr 的話,可以指定 –prefix 選項,

例如下面的指令會將 python 的目錄設定在 /home/testuser/python2.6_wide:

./configure --prefix=/home/testuser/python2.6_wide --with-threads --enable-unicode=ucs4

  

3. 編譯 Python

執行 make 來編譯:

make

 

接著執行 make install 就能將 python 安裝到 /usr/bin 下面了,

但如果系統已經有一個 python 的話,這樣做很有可能會蓋掉系統的 python,

其他相依於這個 python 的套件有可能會掛掉…

 

一種解決方法是用上面提到的 –prefix 指定目錄,這樣 make install 會裝到指定目錄去,

不用擔心會汙染到系統的目錄:

make install

 

另一種是利用 python 提供的 altinstall 方式,

這種方式會將 python 裝到 /usr/local/bin 目錄下,

而且會加上版本號,例如 /usr/local/bin/python2.6,

而函式庫的目錄也是分開的 (跑到 /usr/local/lib/python2.6),不會跟系統的互相影響:

sudo make altinstall

 

用 which 看一下系統預設的 python 和用 make altinstall 的 python 各在哪裡:

[testuser@localhost Python-2.6.8]$ which python
/usr/bin/python
[testuser@localhost Python-2.6.8]$ which python2.6
/usr/local/bin/python2.6

 

這個 python2.6 就是我們剛編譯出來的 wide python 版本,

立刻來試試看它能不能支援超過 0xFFFF 的 Unicode 字元吧:

>>> unichr(0xFFFF)
u'\uffff'
>>> print unichr(0x10000)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode character u'\U00010000' in position 0: ordinal not in range(128)

 

嗯… unichr() 可以接受超過 0xFFFF 的 Unicode 字元了,

可是 print 還是會出現錯誤…

這邊跟 sys.stdout 的編碼有關,有興趣的人再看一下 python: PrintFails 這個連結吧~ 

(其實是我已經有點懶得再追了… 遇到了這個問題的話再說吧 :P)

 

(本頁面已被瀏覽過 960 次)

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料