<?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>生活周遭 &#187; Python</title>
	<atom:link href="http://blog.leirahua.com/tag/python/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.leirahua.com</link>
	<description>In My Circle</description>
	<lastBuildDate>Wed, 27 Jan 2010 15:56:59 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Unicode 与 UTF-8, GBK</title>
		<link>http://blog.leirahua.com/2006/unicode-%e4%b8%8e-utf-8-gbk/</link>
		<comments>http://blog.leirahua.com/2006/unicode-%e4%b8%8e-utf-8-gbk/#comments</comments>
		<pubDate>Fri, 24 Nov 2006 03:29:34 +0000</pubDate>
		<dc:creator>leira</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[unicode]]></category>

		<guid isPermaLink="false">http://blog.leirahua.com/articles/unicode-%e4%b8%8e-utf-8-gbk.html</guid>
		<description><![CDATA[原本是为了回复&#91;python-chinese&#93;邮件列表中的一个关于socket上传输unicode的问题，写得比较长，觉得应该记下来：我想这里有几个概念要澄清~ 这样才能有比较好的交流的基础，而不是说同一个名字，却各自指的不是同一个东西。我也只是班门弄斧，希望大家指正。unicode是一个字符集，不是一种编码，她只是定义了一个字符空间，把字符集中的字符映射到了相应的整数上，并为每一个字符提供了唯一的名字，比如，&#39;中&#39; U+4E2D。但unicode并没有定义编码方式(codec)，也就是从字符集到字节序列的映射方式。有专门为unicode定义的编码方式，比如utf-8,utf-16(be/le)，他们定义了unicode字符到字节序列的映射，也就是编码。utf-16简单的用16bit两个字节来编码(encode)unicode，utf-8用1倒3个或者更多的字节编码(encode)一个unicode字符。这些codec同时也定义了如何从一个字节序列中decode出unicode字符序列的方式。所以，unicode是一个抽象的字符概念，并不是一个字节流，她到字节流的映射靠codec来完成。python中，用unicode对象来表示抽象的unicode字符，我觉得到这个程度就可以了，不必关心其中是不是靠整数来表示的。关键是string对象就是字节流，python的unicode对象不同于string对象，抽象的unicode对象到字节流的string对象之间需要靠codec来转换。(在py3k中可能要统一unicode和string对象，再议)而gbk也是一个字符集，但同时他也定义了gbk这种codec(一种mbcs的codec)，它定义了一个gbk字符(英文或者中文)到字节序列(一个或者两个字节)的映射。因为unicode的集合比gbk大，使gbk的超集，所以，可以把gbk编码的字节流转换成unicode字符序列，也可以把一部分的unicode字符(gbk子集的部分)编码为gbk的字节序列。所以，gbk也可以作为unicode的一种codec来用。比如：(我现在在windows下面，所以默认的编码就是gbk的)>>> sgbkzhong = &#39;中&#39;#输入默认gbk编码的string对象>>> sgbkzhong#这是个以gbk编码的两个字节的字节流&#39;\xd6\xd0&#39;>>> len(sgbkzhong)#所以她的长度是22>>> uzhong=unicode(sgbkzhong,&#39;gbk&#39;)#可以将这个字符序列decode成unicode对象>>> uzhong#这个unicode是U+4E2Du&#39;\u4e2d&#39;>>> len(uzhong)#这个unicode字符序列的长度是11>>> sutf8zhong=uzhong.encode(&#39;utf-8&#39;)>>> sutf8zhong&#39;\xe4\xb8\xad&#39;>>> len(sutf8zhong)#编码成utf-8的字节流，长度是33>>> sutf16bezhong=uzhong.encode(&#39;utf-16be&#39;)>>> sutf16bezhong&#39;N-&#39;>>> len(sutf16bezhong)#编码成utf-16be的字节流，长度是22>>> sutf16bezhong.encode(&#39;hex&#39;)#我们看一下&#39;N-&#39;对应的hex&#39;4e2d&#39;>>> 以上说明的是python中unicode和string(字节流)之间的关系。而socket接口只能传输字节流，她并不关心你的内容是什么，自然也不能传什么抽象的unicode对象，她只能传输将unicode编码过的字节流。所以，python的socket接口只能处理string对象，如果不是string对象，会被首先转换成string对象。具体到你这个问题，On Thu, 23 Nov 2006 13:34:45 +0800, limodou wrote:> On 11/23/06, 隋刚 wrote:>> 实在是头大了，我又尝试了一下，因为是跟vc写的客户端(使用了unicode编码)进>> 行通讯，分析了一下里面的数据，发现在每一个客户端发过来的字符前面加入了>> &#39;00&#39;,而不管我怎么转换，发过去的都是8位的ASCII字符，看看有什么好的解决办>> 法没有？> 那它可能使用的是utf-16-be编码吧。如：> >>> a.encode(&#39;utf-16-be&#39;)> &#39;\x00a&#39;我想limodou已经替你解决了，我的理解和他一样，你的vc的客户端使用的应该是utf-16be的编码，不知道你使用这种方法后的结果怎么样了。至于你之前的代码，为什么直接send unicode对象，对方却接收到的是ascii字符串，原因是send()函数会把你的unicode对象用str()转换成string对象，使用的codec是你指定的&#39;utf-8&#39;，因为都是英文字符，所以，utf-8编码的结果是和ascii一致的。On Mon, 20 Nov 2006 17:58:49 +0800, 隋刚 wrote:> 请问使用python的socket module发送unicode的信息怎么发送，我试着转换了一> 下，发送到服务器端还是ascii的，可以看看我的源程序，谢谢。> import socket> import sys> [...]]]></description>
			<content:encoded><![CDATA[<hr/>原本是为了回复<a href="http://python.cn/mailman/listinfo/python-chinese" target="_blank">&#91;python-chinese&#93;</a>邮件列表中的一个关于<a href="http://python.cn/pipermail/python-chinese/2006-November/032125.html" target="_blank">socket上传输unicode</a>的问题，写得比较长，觉得应该记下来：<br/><br/>我想这里有几个概念要澄清~  这样才能有比较好的交流的基础，而不是说同一个名字，却各自指的不是同一个东西。我也只是班门弄斧，希望大家指正。<br/><br/>unicode是一个字符集，不是一种编码，她只是定义了一个字符空间，把字符集中的字符映射到了相应的整数上，并为每一个字符提供了唯一的名字，比如，&#39;中&#39; U+4E2D。但unicode并没有定义编码方式(codec)，也就是从字符集到字节序列的映射方式。有专门为unicode定义的编码方式，比如utf-8,utf-16(be/le)，他们定义了unicode字符到字节序列的映射，也就是编码。utf-16简单的用16bit两个字节来编码(encode)unicode，utf-8用1倒3个或者更多的字节编码(encode)一个unicode字符。这些codec同时也定义了如何从一个字节序列中decode出unicode字符序列的方式。所以，unicode是一个抽象的字符概念，并不是一个字节流，她到字节流的映射靠codec来完成。python中，用unicode对象来表示抽象的unicode字符，我觉得到这个程度就可以了，不必关心其中是不是靠整数来表示的。关键是string对象就是字节流，python的unicode对象不同于string对象，抽象的unicode对象到字节流的string对象之间需要靠codec来转换。(在py3k中可能要统一unicode和string对象，再议)<br/>而gbk也是一个字符集，但同时他也定义了gbk这种codec(一种mbcs的codec)，它定义了一个gbk字符(英文或者中文)到字节序列(一个或者两个字节)的映射。因为unicode的集合比gbk大，使gbk的超集，所以，可以把gbk编码的字节流转换成unicode字符序列，也可以把一部分的unicode字符(gbk子集的部分)编码为gbk的字节序列。所以，gbk也可以作为unicode的一种codec来用。<span id="more-113406"></span><br/><br/>比如：(我现在在windows下面，所以默认的编码就是gbk的)<br/>>>> sgbkzhong = &#39;中&#39;#输入默认gbk编码的string对象<br/>>>> sgbkzhong#这是个以gbk编码的两个字节的字节流<br/>&#39;\xd6\xd0&#39;<br/>>>> len(sgbkzhong)#所以她的长度是2<br/>2<br/>>>> uzhong=unicode(sgbkzhong,&#39;gbk&#39;)#可以将这个字符序列decode成unicode对象<br/>>>> uzhong#这个unicode是U+4E2D<br/>u&#39;\u4e2d&#39;<br/>>>> len(uzhong)#这个unicode字符序列的长度是1<br/>1<br/>>>> sutf8zhong=uzhong.encode(&#39;utf-8&#39;)<br/>>>> sutf8zhong<br/>&#39;\xe4\xb8\xad&#39;<br/>>>> len(sutf8zhong)#编码成utf-8的字节流，长度是3<br/>3<br/>>>> sutf16bezhong=uzhong.encode(&#39;utf-16be&#39;)<br/>>>> sutf16bezhong<br/>&#39;N-&#39;<br/>>>> len(sutf16bezhong)#编码成utf-16be的字节流，长度是2<br/>2<br/>>>> sutf16bezhong.encode(&#39;hex&#39;)#我们看一下&#39;N-&#39;对应的hex<br/>&#39;4e2d&#39;<br/>>>> <br/><br/>以上说明的是python中unicode和string(字节流)之间的关系。而socket接口只能传输字节流，她并不关心你的内容是什么，自然也不能传什么抽象的unicode对象，她只能传输将unicode编码过的字节流。所以，python的socket接口只能处理string对象，如果不是string对象，会被首先转换成string对象。<br/><br/><br/>具体到你这个问题，<br/><br/>On Thu, 23 Nov 2006 13:34:45 +0800, limodou <br/>
<limodou@gmail.com> wrote:<br/><br/>> On 11/23/06, 隋刚 <blackjacksg@gmail.com> wrote:<br/>>> 实在是头大了，我又尝试了一下，因为是跟vc写的客户端(使用了unicode编码)进<br/>>> 行通讯，分析了一下里面的数据，发现在每一个客户端发过来的字符前面加入了<br/>>> &#39;00&#39;,而不管我怎么转换，发过去的都是8位的ASCII字符，看看有什么好的解决办<br/>>> 法没有？<br/>> 那它可能使用的是utf-16-be编码吧。如：<br/>> >>> a.encode(&#39;utf-16-be&#39;)<br/>>  &#39;\x00a&#39;<br/><br/>我想limodou已经替你解决了，我的理解和他一样，你的vc的客户端使用的应该是utf-16be的编码，不知道你使用这种方法后的结果怎么样了。<br/><br/>至于你之前的代码，为什么直接send unicode对象，对方却接收到的是ascii字符串，原因是send()函数会把你的unicode对象用str()转换成string对象，使用的codec是你指定的&#39;utf-8&#39;，因为都是英文字符，所以，utf-8编码的结果是和ascii一致的。<br/><br/>On Mon, 20 Nov 2006 17:58:49 +0800, 隋刚 <br/><blackjacksg@gmail.com> wrote:<br/><br/>> 请问使用python的socket module发送unicode的信息怎么发送，我试着转换了一<br/>> 下，发送到服务器端还是ascii的，可以看看我的源程序，谢谢。<br/>> import socket<br/>> import sys<br/>> reload(sys)<br/>> sys.setdefaultencoding(&#39;utf-8&#39;)<br/>> host = &#8220;192.168.3.111&#8243;<br/>> port = 8888<br/>> s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)<br/>> s.connect((host, port));<br/>> str = u&#39;<?xml version=\"1.0\" ?><request type=\"Distribute\"/>&#39;<br/>> s.send(str)<br/>> date = s.recvfrom(4096)<br/>> s.close()<br/>> print repr(date)<br/><br/><br/>顺便推荐一下这篇FAQ，对Unicode讲解得很通透，让我明白了很多原先很混乱的概念。<br/><a href="http://www.cl.cam.ac.uk/~mgk25/unicode.html" target="_blank">UTF-8 and Unicode FAQ for Unix/Linux</a><br/>这儿有一个捎老一点的<a href="http://www.linuxforum.net/books/UTF-8-Unicode.html" target="_blank">中文版</a><br/><br/></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.leirahua.com/2006/unicode-%e4%b8%8e-utf-8-gbk/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Pyrex, 和Python的C扩展</title>
		<link>http://blog.leirahua.com/2006/pyrex-%e5%92%8cpython%e7%9a%84c%e6%89%a9%e5%b1%95/</link>
		<comments>http://blog.leirahua.com/2006/pyrex-%e5%92%8cpython%e7%9a%84c%e6%89%a9%e5%b1%95/#comments</comments>
		<pubDate>Fri, 02 Jun 2006 04:34:11 +0000</pubDate>
		<dc:creator>leira</dc:creator>
				<category><![CDATA[Python]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[pyrex]]></category>

		<guid isPermaLink="false">http://blog.leirahua.com/articles/pyrex-%e5%92%8cpython%e7%9a%84c%e6%89%a9%e5%b1%95.html</guid>
		<description><![CDATA[这原本是回复到[python-chinese]邮件列表的，但是没有回复进去，可能是因为功过Gmane news服务器的原因。先转到这儿： 倒是这两天我也在看这方面的问题~ 一般编写Python C/C++ Module，或者为C/C++ lib编写Wrapper，我所看到的有以下几种方式： 1. 直接使用C Python提供的API 2. SWIG 3. Boost.Python 4. Pyrex 首先直接使用Python C API是很不方便的。上面几位高人已经谈过了SWIG和Boost.Python，我就不多说了，只是个人感觉易用性而言Boost.Python > SWIG，但SWIG功能强大，支持的也不只是Python一种脚本语言。以上这两种方式对C++的支持都比较友好。 这里着重推荐一下Pyrex。 Pyrex可以说是扩展Python的一大创新，她使用Python like的语法来编写Python的C Module，自动翻译成C语言代码，进而编译获取C代码的高效率。而且，配合Python的Distutils，使得构建过程简单到了只需要setup.py的程度。我觉得其简化python扩展的编写方式，已经和Boost.python,SWIG不在一个意义级别上了。 这里贴一段来自pyrex的示例，用于搜索质数： # primes.pyx # # Calculate prime numbers # def primes(int kmax): cdef int n, k, i cdef int p[1000] result = [] if kmax > 1000: kmax = 1000 [...]]]></description>
			<content:encoded><![CDATA[<hr/>
<p>这原本是回复到[python-chinese]邮件列表的，但是没有回复进去，可能是因为功过Gmane news服务器的原因。先转到这儿：</p>
<p>倒是这两天我也在看这方面的问题~<br/><br />
一般编写Python C/C++ Module，或者为C/C++ lib编写Wrapper，我所看到的有以下几种方式：<br />
1. 直接使用C Python提供的API<br />
2. SWIG<br />
3. Boost.Python<br />
4. Pyrex</p>
<p>首先直接使用Python C API是很不方便的。上面几位高人已经谈过了SWIG和Boost.Python，我就不多说了，只是个人感觉易用性而言Boost.Python > SWIG，但SWIG功能强大，支持的也不只是Python一种脚本语言。以上这两种方式对C++的支持都比较友好。</p>
<p>这里着重推荐一下<a href="http://www.cosc.canterbury.ac.nz/~greg/python/Pyrex/">Pyrex</a>。<br />
Pyrex可以说是扩展Python的一大创新，她使用Python like的语法来编写Python的C Module，自动翻译成C语言代码，进而编译获取C代码的高效率。而且，配合Python的Distutils，使得构建过程简单到了只需要setup.py的程度。我觉得其简化python扩展的编写方式，已经和Boost.python,SWIG不在一个意义级别上了。</p>
<p>这里贴一段来自pyrex的示例，用于搜索质数：</p>
<pre class="brush: python">
# primes.pyx
#
#  Calculate prime numbers
#

def primes(int kmax):
        cdef int n, k, i
        cdef int p[1000]
        result = []
        if kmax > 1000:
                kmax = 1000
        k = 0
        n = 2
        while k < kmax:
                i = 0
                while i < k and n % p[i] <> 0:
                        i = i + 1
                if i == k:
                        p[k] = n
                        k = k + 1
                        result.append(n)
                n = n + 1
        return result
</pre>
<p>将其pyrexc编译后得到一个c文件，然后编译之后就是一个python module了~ 按照他的逻辑，我还对照相应的写了一个Python脚本：</p>
<pre class="brush: python">
#!/usr/bin/env python
# primespy.py

def primes(kmax):
        result = []
        if kmax > 1000:
                kmax = 1000
        k = 0
        n = 2
        while k < kmax:
                i = 0
                while i< k and n % result[i] != 0:
                        i += 1
                if i == k:
                        result.append(n)
                        k += 1
                n+=1
        return result
</pre>
<p>两者的代码行数基本一样,来看一下运行结果:</p>
<pre>
In [23]: tpyx = timeit.Timer(stmt=&#39;primes.primes(1000)&#39;, setup=&#39;import primes&#39;)

In [24]: tpy = timeit.Timer(stmt=&#39;primespy.primes(1000)&#39;, setup=&#39;import primespy&#39;)

In [25]: tpyx.timeit(100)
Out[25]: 1.2969999313354492

In [26]: tpy.timeit(100)
Out[26]: 30.266000032424927
</pre>
<p>速度提高了30倍之多！</p>
<p>pyrex的优势是编写简单，不必处理多余的细节，而且也不需要为这种简单付出效率的代价。劣势在于目前的pyrex对C++的只是仍然不是很好，还在继续开发之中。至于对C++到地支持差到什么程度，我还没有进一步测试过，还希望看到各位的高见。</p>
<p>总结是，如果是针对C的Python扩展，或者lib Wrapper，Pyrex可以说是最方便的选择。如果涉及到C++的扩展，可<br />
能目前boost.python还是最好的选择了。</p>
<p>补：目前正在看Boost.python，SWIG其实并没有细看过，呵呵，只是看了一些intro性质文章，就开始大发厥词了，希望大家补充指正。</p>
</p>
</p>
</p></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.leirahua.com/2006/pyrex-%e5%92%8cpython%e7%9a%84c%e6%89%a9%e5%b1%95/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
