浏览模式: 标准 | 列表 | 订阅

python可变参数与标准输出的重定位

作者:ciniao 时间:2011-09-27 分类:python 2 Comments

    使用python的内置函数print时,大家会发现它是支持任意多个参数,也就是说,print的调用参数是不固定的。例如:
print "你好"
print "我是",name
print "现在是", time , " 你在干什么呢", name , "!"

    这得益与python的“可变参数”,在Python里,可以使用*和**来设置可变参数,它们的区别是*传递一个参数元组,**传递一个参数字典,二者可以同时混合使用。混合使用时要加些小心,因为python中他们的次序是重要的。参数归为4类,不是所有的类别都需要。他们必须按下面的次序定义,不用的可以跳过。
    1)必须的参数
    2)可选的参数
    3)过量的位置参数
    4)过量的关键字参数
def funName(a, b=None, *c, **d):
    这个次序是必须的,因为*args和**kwargs只接受那些没有放进来的其他任何参数。没有这个次序,当你调用一个带有位置参数的函数,python就不知道哪个值是已声明参数想要的,也不知道哪个被作为过量参数对待。
    也要注意的是,当函数能接受许多必须的参数和可选的参数,那它只要定义一个过量的参数类型即可。看下面的例子:
def add(a, b, c):
    return a + b + c
>>> add(1, 2, 3)
6
>>> add(a=4, b=5, c=6)
15
>>> args = (2, 3)
>>> add(1, *args)
6
>>> kwargs={'b': 8, 'c': 9}
>>> add(a=7, **kwargs)
24
>>> add(a=7, *args)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: add() got multiple values for keyword argument 'a'
>>> add(1, 2, a=7)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: add() got multiple values for keyword argument 'a'

    注意这个例子的最后几行,特别留意当传递一个元组作为可变参数时,是否要显式的传递关键字参数。因为python使用次序规则来扩展过量的参数,那位置参数要放在前面。这个例子中,最后两个调用是相同的,python不能决定那个值是给a的。

    下面举一个例子来模仿print的实现:
>>> import sys
>>> def myprint(*argv):
    sys.stdout.write(" ".join([str(i) for i in argv]) + "\n")

>>> print "I believe", 2012, "is the end of the world."
I believe 2012 is the end of the world.
>>> myprint("I believe", 2012, "is the end of the world.")
I believe 2012 is the end of the world.
>>> print "tuple:", (1, 2, 3), "list:", [1, 2, 3], "dict:", {"begin":-2012, "end":2012}
tuple: (1, 2, 3) list: [1, 2, 3] dict: {'begin': -2012, 'end': 2012}
>>> myprint("tuple:", (1, 2, 3), "list:", [1, 2, 3], "dict:", {"begin":-2012, "end":2012})
tuple: (1, 2, 3) list: [1, 2, 3] dict: {'begin': -2012, 'end': 2012}

    print默认是输出到stdout中,在终端运行的程序,无重定向的情况下,print输出到控制台。如果要做代码里实现把print的输出写入到log文件中,可以通过修改stdout的文件对象来实现。同理,重定位标准输入和标准错误输出分别修改stdin和stderr的文件对象即可。
    下面的例子捕捉所有print的输出,让输出的每一行前增加一个时间的显示:
import sys, time
class MyOutput():
    def __init__(self, fd):
        self.formatTime()
        self.out = fd
        self.newLine = True
    def formatTime(self):
        return time.strftime("%H:%M:%S  ", time.localtime())
    def write(self, s):
        if self.newLine:
            self.out.write(self.formatTime())
            self.newLine = False
        self.out.write(s)
        if s.endswith("\n"):
            self.newLine = True
    def flush(self):
        self.out.flush()
sys.stdout = MyOutput(sys.stdout)

print "Program begin."
mylist = [5, 4, 3, 2, 1]
print "prev:  ", mylist
mylist.sort()
print "after: ", mylist
time.sleep(3)
print "Program end."

运行效果如下图:


本文部分内容来源于:http://xiaoxia.org/?p=4270

python中的异常处理

作者:ciniao 时间:2011-09-24 分类:python 1 Comments

    Python的异常处理能力是很强大的,可向用户准确反馈出错信息。在Python中,异常也是对象,可对它进行操作。所有异常都是基类Exception的成员,所有异常都从基类Exception继承,而且都在exceptions模块中定义,Python自动将所有异常名称放在内建命名空间中,所以程序不必导入exceptions模块即可使用异常。
    一旦引发而且没有捕捉SystemExit异常,程序执行就会终止。如果交互式会话遇到一个未被捕捉的SystemExit异常,会话就会终止。
    一、异常的捕获
    异常的捕获有以下几种方法:
    1:使用try和except语句
try:
    block
except [exception,[data…]]:
    block

try:
    block
except [exception,[data...]]:
    block
else:
    block

该种异常处理语法的规则是:
• 执行try下的语句,如果引发异常,则执行过程会跳到第一个except语句。
• 如果第一个except中定义的异常与引发的异常匹配,则执行该except中的语句。
• 如果引发的异常不匹配第一个except,则会搜索第二个except,允许编写的except数量没有限制。
• 如果所有的except都不匹配,则异常会传递到下一个调用本代码的最高层try代码中。
• 如果没有发生异常,则执行else块代码。
示例代码:
try:
    f = open(“file.txt”,”r”)
except IOError, e:
    print e

    捕获到的IOError错误的详细原因会被放置在对象e中,然后运行该异常的except代码块,也可以使用以下方法来捕获所有的异常:
try:
    a=b
    b=c
except Exception,ex:
    print Exception,":",ex

    使用except子句需要注意的事情,就是多个except子句截获异常时,如果各个异常类之间具有继承关系,则子类应该写在前面,否则父类将会直接截获子类异常,放在后面的子类异常也就不会执行到了。

    2:使用try跟finally
try:
    block
finally:
    block

该语句的执行规则是:
• 执行try下的代码。
• 如果发生异常,在该异常传递到下一级try时,执行finally中的代码。
• 如果没有发生异常,则执行finally中的代码。

    第二种try语法在无论有没有发生异常都要执行代码的情况下是很有用的,例如我们在python中打开一个文件进行读写操作,我在操作过程中不管是否出现异常,最终都是要把该文件关闭的。
    这两种形式相互冲突,使用了一种就不允许使用另一种,而功能又各异。

    二、手工引发引发一个异常
    在Python中,要想引发异常,最简单的形式就是输入关键字raise,后跟要引发的异常的名称。异常名称标识出具体的类:Python异常是那些类的对象,执行raise语句时,Python会创建指定的异常类的一个对象,raise语句还可指定对异常对象进行初始化的参数,为此,请在异常类的名称后添加一个逗号以及指定的参数(或者由参数构成的一个元组)。
示例代码:
try:
    raise MyError #自己抛出一个异常
except MyError:
    print 'a error'

raise ValueError,'invalid argument'
捕捉到的内容为:
type = VauleError
message = invalid argument

    三、跟踪查看异常
    发生异常时,Python能“记住”引发的异常以及程序的当前状态,Python还维护着traceback(跟踪)对象,其中含有异常发生时与函数调用堆栈有关的信息,异常可能在一系列嵌套较深的函数调用中引发,程序调用每个函数时,Python会在“函数调用堆栈”的起始处插入函数名,一旦异常被引发,Python会搜索一个相应的异常处理程序。
    如果当前函数中没有异常处理程序,当前函数会终止执行,Python会搜索当前函数的调用函数,并以此类推,直到发现匹配的异常处理程序,或者Python抵达主程序为止,这一查找合适的异常处理程序的过程就称为“堆栈辗转开解”(Stack Unwinding)。解释器一方面维护着与放置堆栈中的函数有关的信息,另一方面也维护着与已从堆栈中“辗转开解”的函数有关的信息。
try:
    block
except:
    traceback.print_exc()

    四、采用sys模块回溯最后的异常
import sys
try:
    block
except:
    info=sys.exc_info()
    print info[0],":",info[1]

或者以如下的形式:
import sys
    tp,val,td = sys.exc_info()
    sys.exc_info()的返回值是一个tuple, (type, value/message, traceback)
    这里的type是异常的类型,value/message是异常的信息或者参数,traceback包含调用栈信息的对象,从这点上可以看出此方法涵盖了traceback。

    以上都是错误处理的理论知识,接下来我们要动手设计一个自己的异常处理类,用来记录异常日志,将错误的日志按照每小时一个文件的频率,保存到我们指定的位置。代码如下:
#coding:utf-8
#基于python2.6
import logging,os,time,traceback
class LOG:
    def __init__(self,logger):
        self.fileHandlerName = ''
        self.fileHandler = None
        self.loggerName = logger
        self.logger = logging.getLogger(logger)
        self.logger.setLevel(logging.DEBUG)
        self.formatter = logging.Formatter("=========================\ntime:%(asctime)s \nlogger:%(name)s \nlevel:%(levelname)s \nfile:%(filename)s \nfun:%(funcName)s \nlineno:%(lineno)d \nmessage:%(message)s")

        # 控制台
        ch = logging.StreamHandler()
        ch.setLevel(logging.DEBUG)
        ch.setFormatter(self.formatter)
        self.logger.addHandler(ch)

        path = os.path.abspath(os.path.dirname(__file__)) + '/log/'+self.loggerName+'/'
        print 'log path=',path
    
    def setfh(self):
        fname = time.strftime("%Y%m%d%H")
        if fname!=self.fileHandlerName:
            #移除原来的句柄
            if self.fileHandler!=None : 
                self.logger.removeHandler(self.fileHandler)
            #设置日志文件保存位置
            path = os.path.abspath(os.path.dirname(__file__)) + '/log/'+self.loggerName+'/'
            print path
            if os.path.isdir(path) == False:
                os.makedirs(path)
            fh = logging.FileHandler(path+fname+'.log')
            fh.setLevel(logging.DEBUG)
            fh.setFormatter(self.formatter)
            self.logger.addHandler(fh)

            self.fileHandlerName = fname
            self.fileHandler = fh
    #格式化日志内容
    def _fmtInfo(self,msg):
        if len(msg)==0:
            msg = traceback.format_exc()
            return msg
        else:
            _tmp = [msg[0]]
            _tmp.append(traceback.format_exc())
            return '\n**********\n'.join(_tmp)
    #封装方法
    def debug(self,*msg):
        _info = self._fmtInfo(msg)
        try:
            self.setfh()
            self.logger.debug(_info)
        except:
            print 'mylog debug:' + _info
    def error(self,*msg):
        _info = self._fmtInfo(msg)
        try:
            self.setfh()
            self.logger.error(_info)
        except:
            print 'mylog error:' + _info
    def info(self,*msg):
        _info = self._fmtInfo(msg)
        try:
            self.setfh()
            self.logger.error(_info)
        except:
            print 'mylog info:' + _info
    def warning(self,*msg):
        _info = self._fmtInfo(msg)
        try:
            self.setfh()
            self.logger.error(_info)
        except:
            print 'mylog warning:' + _info
        

if __name__=='__main__':
    log = LOG('fight')
    try:
        print 1/0
    except:
        log.error() #使用系统自己的错误描述
    try:
        print 2/0
    except:
        log.error('搞错了,分母不能为0') #使用自己的错误描述

    运行一下,我们会在该文件目录下的log/fight下看到一个日志文件,记录的描述内容如下:

#文章部分内容来源于网络,作者不详 无法署名#

python中用ctypes模块调用C语言库

作者:ciniao 时间:2011-09-13 分类:python 2 Comments

    最近用到中文分词库 Bamboo ,开始时有点头疼居然没有 Python 封装,后来发现用 ctypes 模块来封装实在是太简单、太方便了~几乎被感动到内流满面~有了庞大 C 库和 ctypes 模块的 Python ,真是可比当年的数理化——走遍天下都不怕~下面给出通过 ctypes 模块调用 Bamboo 分词的示例代码:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from ctypes import *
# 通过 C 接口载入 libbamboo ,.dylib是 Mac OSX 下的动态库后缀, Linux 下应该是libbamboo.so
libbamboo = CDLL('libbamboo.dylib')
# 调用 bamboo_init() 函数得到一个分词器实例
bamboo_init = libbamboo.bamboo_init
bamboo_init.restype = c_void_p
bamboo_handler = bamboo_init(c_char_p('crf_seg'), None)
# 如果返回的实例是 None (也即 C 中的 Null ),表示实例生成失败,那我们打印出错原因
if bamboo_handler is None:
    bamboo_strerror = libbamboo.bamboo_strerror
    bamboo_strerror.restype = c_char_p
    print bamboo_strerror()
else:
    # 把文本传给分词器准备分词
    # 待分词的文本必须是 utf-8 编码的 bytes string ,所以我们要把 unicode string encode 一下
    libbamboo.bamboo_setopt(bamboo_handler, c_long(0), c_char_p(u'我爱北京天安门'.encode('utf-8')))
    # 真正开始分词
    bamboo_parse = libbamboo.bamboo_parse
    bamboo_parse.restype = c_char_p
    # 下一行得到分词结果(空格分隔),格式还是 utf-8 编码的 bytes string ,我们把它 decode 成 unicode 
    segged = bamboo_parse(bamboo_handler).decode('utf-8')
    print type(segged), len(segged), segged
# 调用 bamboo_clean() 函数释放分词器实例
libbamboo.bamboo_clean(bamboo_handler) 

相关文章:沈崴大侠的《用 Python 写自己的 C Module》
本文作者:Elias的邪异门
文章转自:http://blog.elias.cn/archives/399

用python来开发webgame服务端(5)

作者:ciniao 时间:2011-09-06 分类:python 9 Comments

    刺鸟原创文章,转载请注明出处
    在前面的文章中,我们已经开始了不少逻辑功能的开发,在这期间也有不少可以分享的经验点,这个我们以后慢慢道来。今天,我们主要讨论下如何让服务端能进行分布式部署和工作。

    一:为什么要支持分布式部署和开发
    众所周知,python是单线程的语言,存在GIL锁、无法利用多核CPU等诸多限制,为了能让服务端能承载更多的用户,我们必须让程序能在逻辑上、甚至物理上分开,当用户达到一定数量的时候,我们能新开一个进程来响应请求,或多加一台服务器来处理请求。这样就能达到理论上无限扩展的可能性。

    二:如何让程序能达到上述效果
    我们简单分析下我们的服务端要实现的功能:
    战斗服务器:
    通过之前的文章可以知道,我们的战斗是类似回合制的战斗模式,每场战斗之间的数据是无关联的,仅需要处理战斗中各玩家之间的数据交互即可,这很容易可以让逻辑分开处理。
    地图服务器:
    每个地图之间的玩家,在大部分时间里,也是不需要交互的,因此我们可以按地图来处理逻辑,在切换地图时,若下一张地图的服务进程在其他服务器,则先将当前地图的数据保存到memcache,连接到下一个服务器的时候,在从memcache中将数据取回即可。
    聊天服务器:
    在不同的地图的玩家,会存在聊天的交互(比如:私聊,世界频道,公告频道等),因此所有的玩家都需要连接至一个公共的聊天服务进程,来达到数据交互的目的。

    三:源代码
    下面,我以战斗服务器为例来看看,首先,得有一个主调度进程,客户端在进入战斗前,先连接该进程,该进程在收到请求后,根据各战斗逻辑进程当前玩家的数量,来判定是否需要开启新的进程,并返回当前人数最少的进程的IP:PORT。

    我通过以下方法来开启战斗进程:
FIGHTNUM = {}
MAXNUM = 1000 #每个进程的承载上限 超过该值自动新开启一个服务进程
NOWFIGHTPORT = 7000 #战斗服务进程初始端口

#开启一个新的战斗服务进程
import subprocess
def openFight():
    global NOWFIGHTPORT,FIGHTNUM
    FIGHTNUM[NOWFIGHTPORT] = 0 #该服务器当前战斗数
    subprocess.Popen('python '+os.getcwd()+'/fightserver.py ' + str(NOWFIGHTPORT)+' &',shell=True) #运行脚本
    NOWFIGHTPORT = NOWFIGHTPORT + 1
openFight() #初始化,开启一个服务进程

新建一个调动服务进程,在dataReceived时处理:
def dataReceived(self, data):
    global MAXNUM
    msgArr = data.split('|')
    if msgArr[0] == 'get':
        n = sorted(FIGHTNUM.items(), key=lambda d: d[1]) #按value低->高排序
        #达到预设上限,开启新进程
        if n[0][1]>=MAXNUM:
            openFight()
            p = NOWFIGHTPORT #返回新开启的进程的port
        else:
            p = n[0][0] #返回人数最少的进程的port
        client.transport.write(str(p))
    elif msgArr[0] == 'add':
        FIGHTNUM[msgArr[1]] = FIGHTNUM[msgArr[1]] + 1
    elif msgArr[0] == 'del':
        FIGHTNUM[msgArr[1]] = FIGHTNUM[msgArr[1]] - 1
    client.transport.loseConnection()

    在进入战斗前,连接调度进程的端口,并发送'get',调度程序会返回一个战斗进程的port,客户端连接该port,连接成功后,向调度端口发送'add|7001',战斗结束时,向调度端口发送'del|7001'(其中的7001为战斗服务器监听的端口),这样即可达到在同服务器分布的目的,实现了这一步,那跨服务器的分布也就变得很容易了。
    对于地图服务器也可以采用类似的处理方法,完善以上功能后,我们的服务端就变得更加强壮了,承载人数方面可以也可以多了一个保障。

#本文由刺鸟原创,欢迎转载,但请保留出处,也欢迎对本文感兴趣的同学多多交流。#

python获取汉字的拼音

作者:ciniao 时间:2011-09-05 分类:python 4 Comments

    某项目,要实现支持通过拼音查找指定关键词的功能,最简单的方法应该是在录入数据的时候,把内容的拼音先获取出来,一并保存到数据库,以便查询。
    因此有了下面的def,不知道你是否有更高效的办法呢?
#coding:utf-8
#基于python2.6
table = 'a,-20319;ai,-20317;an,-20304;ang,-20295;ao,-20292;ba,-20283;bai,-20265;ban,-20257;bang,-20242;bao,-20230;bei,-20051;ben,-20036;beng,-20032;bi,-20026;bian,-20002;biao,-19990;bie,-19986;bin,-19982;bing,-19976;bo,-19805;bu,-19784;ca,-19775;cai,-19774;can,-19763;cang,-19756;cao,-19751;ce,-19746;ceng,-19741;cha,-19739;chai,-19728;chan,-19725;chang,-19715;chao,-19540;che,-19531;chen,-19525;cheng,-19515;chi,-19500;chong,-19484;chou,-19479;chu,-19467;chuai,-19289;chuan,-19288;chuang,-19281;chui,-19275;chun,-19270;chuo,-19263;ci,-19261;cong,-19249;cou,-19243;cu,-19242;cuan,-19238;cui,-19235;cun,-19227;cuo,-19224;da,-19218;dai,-19212;dan,-19038;dang,-19023;dao,-19018;de,-19006;deng,-19003;di,-18996;dian,-18977;diao,-18961;die,-18952;ding,-18783;diu,-18774;dong,-18773;dou,-18763;du,-18756;duan,-18741;dui,-18735;dun,-18731;duo,-18722;e,-18710;en,-18697;er,-18696;fa,-18526;fan,-18518;fang,-18501;fei,-18490;fen,-18478;feng,-18463;fo,-18448;fou,-18447;fu,-18446;ga,-18239;gai,-18237;gan,-18231;gang,-18220;gao,-18211;ge,-18201;gei,-18184;gen,-18183;geng,-18181;gong,-18012;gou,-17997;gu,-17988;gua,-17970;guai,-17964;guan,-17961;guang,-17950;gui,-17947;gun,-17931;guo,-17928;ha,-17922;hai,-17759;han,-17752;hang,-17733;hao,-17730;he,-17721;hei,-17703;hen,-17701;heng,-17697;hong,-17692;hou,-17683;hu,-17676;hua,-17496;huai,-17487;huan,-17482;huang,-17468;hui,-17454;hun,-17433;huo,-17427;ji,-17417;jia,-17202;jian,-17185;jiang,-16983;jiao,-16970;jie,-16942;jin,-16915;jing,-16733;jiong,-16708;jiu,-16706;ju,-16689;juan,-16664;jue,-16657;jun,-16647;ka,-16474;kai,-16470;kan,-16465;kang,-16459;kao,-16452;ke,-16448;ken,-16433;keng,-16429;kong,-16427;kou,-16423;ku,-16419;kua,-16412;kuai,-16407;kuan,-16403;kuang,-16401;kui,-16393;kun,-16220;kuo,-16216;la,-16212;lai,-16205;lan,-16202;lang,-16187;lao,-16180;le,-16171;lei,-16169;leng,-16158;li,-16155;lia,-15959;lian,-15958;liang,-15944;liao,-15933;lie,-15920;lin,-15915;ling,-15903;liu,-15889;long,-15878;lou,-15707;lu,-15701;lv,-15681;luan,-15667;lue,-15661;lun,-15659;luo,-15652;ma,-15640;mai,-15631;man,-15625;mang,-15454;mao,-15448;me,-15436;mei,-15435;men,-15419;meng,-15416;mi,-15408;mian,-15394;miao,-15385;mie,-15377;min,-15375;ming,-15369;miu,-15363;mo,-15362;mou,-15183;mu,-15180;na,-15165;nai,-15158;nan,-15153;nang,-15150;nao,-15149;ne,-15144;nei,-15143;nen,-15141;neng,-15140;ni,-15139;nian,-15128;niang,-15121;niao,-15119;nie,-15117;nin,-15110;ning,-15109;niu,-14941;nong,-14937;nu,-14933;nv,-14930;nuan,-14929;nue,-14928;nuo,-14926;o,-14922;ou,-14921;pa,-14914;pai,-14908;pan,-14902;pang,-14894;pao,-14889;pei,-14882;pen,-14873;peng,-14871;pi,-14857;pian,-14678;piao,-14674;pie,-14670;pin,-14668;ping,-14663;po,-14654;pu,-14645;qi,-14630;qia,-14594;qian,-14429;qiang,-14407;qiao,-14399;qie,-14384;qin,-14379;qing,-14368;qiong,-14355;qiu,-14353;qu,-14345;quan,-14170;que,-14159;qun,-14151;ran,-14149;rang,-14145;rao,-14140;re,-14137;ren,-14135;reng,-14125;ri,-14123;rong,-14122;rou,-14112;ru,-14109;ruan,-14099;rui,-14097;run,-14094;ruo,-14092;sa,-14090;sai,-14087;san,-14083;sang,-13917;sao,-13914;se,-13910;sen,-13907;seng,-13906;sha,-13905;shai,-13896;shan,-13894;shang,-13878;shao,-13870;she,-13859;shen,-13847;sheng,-13831;shi,-13658;shou,-13611;shu,-13601;shua,-13406;shuai,-13404;shuan,-13400;shuang,-13398;shui,-13395;shun,-13391;shuo,-13387;si,-13383;song,-13367;sou,-13359;su,-13356;suan,-13343;sui,-13340;sun,-13329;suo,-13326;ta,-13318;tai,-13147;tan,-13138;tang,-13120;tao,-13107;te,-13096;teng,-13095;ti,-13091;tian,-13076;tiao,-13068;tie,-13063;ting,-13060;tong,-12888;tou,-12875;tu,-12871;tuan,-12860;tui,-12858;tun,-12852;tuo,-12849;wa,-12838;wai,-12831;wan,-12829;wang,-12812;wei,-12802;wen,-12607;weng,-12597;wo,-12594;wu,-12585;xi,-12556;xia,-12359;xian,-12346;xiang,-12320;xiao,-12300;xie,-12120;xin,-12099;xing,-12089;xiong,-12074;xiu,-12067;xu,-12058;xuan,-12039;xue,-11867;xun,-11861;ya,-11847;yan,-11831;yang,-11798;yao,-11781;ye,-11604;yi,-11589;yin,-11536;ying,-11358;yo,-11340;yong,-11339;you,-11324;yu,-11303;yuan,-11097;yue,-11077;yun,-11067;za,-11055;zai,-11052;zan,-11045;zang,-11041;zao,-11038;ze,-11024;zei,-11020;zen,-11019;zeng,-11018;zha,-11014;zhai,-10838;zhan,-10832;zhang,-10815;zhao,-10800;zhe,-10790;zhen,-10780;zheng,-10764;zhi,-10587;zhong,-10544;zhou,-10533;zhu,-10519;zhua,-10331;zhuai,-10329;zhuan,-10328;zhuang,-10322;zhui,-10315;zhun,-10309;zhuo,-10307;zi,-10296;zong,-10281;zou,-10274;zu,-10270;zuan,-10262;zui,-10260;zun,-10256;zuo,-10254'

def Pinyin(num):
    global table
    if num>0 & num<160:
        return chr(num)
    v=table.split(';')
    for i in xrange(len(v)-1,-1,-1):
        s=v[i].split(',')
        if int(s[1])<=num:
            return s[0]
            break
    
if __name__ == "__main__": 
    chinese = '我是刺鸟 你是谁'
    i=0
    while(i<len(chinese)-1):
        p = ord(chinese[i:i+1])
        if(p>160):
            i+=1
            q = ord(chinese[i:i+1])
            p = p*256+q-65536
        i+=1
        print Pinyin(p)

运行结果: