hongqn: 你的python内部是用什么编码表示unicode的?
你的python内部是用什么编码表示unicode的?
在comp.lang.python上看到关于unicode转换的一个线索,Christos TZOTZIOY Georgiou给出了判断python内部表示unicode的编码的方式--使用sys.maxunicode。
如果sys.maxunicode的返回值是65535,说明python是用--enable-unicode=ucs2编译的,如果返回值是1114111,说明是用--enable-unicode=ucs4编译的。
在我的gentoo上实验结果如下:In [1]: import sys
In [2]: sys.maxunicode
Out[2]: 1114111
呵呵,是使用UCS-4表示unicode的,就算是很生僻很生僻的字也能处理哦
由于好奇,又看了看/usr/portage/dev-lang/python/python-2.3.4-r1.ebuild,想看看gentoo是如何判断采用什么参数编译python的。
相关的代码如下:# super-secret switch. don't use this unless you know what you're # doing. enabling UCS2 support will break your existing python # modules use ucs2 \ && myconf="${myconf} --enable-unicode=ucs2" \ || myconf="${myconf} --enable-unicode=ucs4"
是使用ucs2这个use flag来定义--enable-unicode的。当激活ucs2,就采用--enable-unicode=ucs2,当ucs2被disable时,就采用--enable-unicode=ucs4。
那么如果是手工编译python,不给出--enable-unicode的话,python又会如何处理呢?看看Python的安装代码吧。$ tar jxf /usr/portage/distfiles/Python-2.3.4.tar.bz2 $ cd Python-2.3.4 $ ./configure --help | grep unicode -u1 --disable-ipv6 Disable ipv6 support --enable-unicode[=ucs[24]] Enable Unicode strings (default is yes)
默认的--enable-unicode的参数是yes。那么到底是ucs2还是ucs4呢?检查configure的源码吧echo "$as_me:$LINENO: checking what type to use for unicode" >&5 echo $ECHO_N "checking what type to use for unicode... $ECHO_C" >&6 # Check whether --enable-unicode or --disable-unicode was given. if test "${enable_unicode+set}" = set; then enableval="$enable_unicode" else enable_unicode=yes fi; if test $enable_unicode = yes then # Without any arguments, Py_UNICODE defaults to two-byte mode case "$have_ucs4_tcl" in yes) enable_unicode="ucs4" ;; *) enable_unicode="ucs2" ;; esac fi case "$enable_unicode" in ucs2) unicode_size="2" cat >>confdefs.h <<\_ACEOF #define Py_UNICODE_SIZE 2 _ACEOF ;; ucs4) unicode_size="4" cat >>confdefs.h <<\_ACEOF #define Py_UNICODE_SIZE 4 _ACEOF ;; esac
可以看出,当--enable-unicode=yes时,configure是根据$have_ucs4_tcl的值来决定是使用UCS-2还是UCS-4,并体现在Py_UNICODE_SIZE宏中。echo "$as_me:$LINENO: checking for UCS-4 tcl" >&5 echo $ECHO_N "checking for UCS-4 tcl... $ECHO_C" >&6 have_ucs4_tcl=no cat >conftest.$ac_ext <<_ACEOF #line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include <tcl.h> #if TCL_UTF_MAX != 6 # error "NOT UCS4_TCL" #endif int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 (eval $ac_compile) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='test -s conftest.$ac_objext' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cat >>confdefs.h <<\_ACEOF #define HAVE_UCS4_TCL 1 _ACEOF have_ucs4_tcl=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f conftest.$ac_objext conftest.$ac_ext echo "$as_me:$LINENO: result: $have_ucs4_tcl" >&5 echo "${ECHO_T}$have_ucs4_tcl" >&6
原来是根据tcl.h中TCL_UTF_MAX宏是否为6来判断的,如果为6,则使用UCS-4,如果不为6(包括未定义),则使用UCS-2。