类型:Python,创建时间:Jan. 1, 2012, 5:32 p.m.
标题无“转载”即原创文章,版权所有。转载请注明来源:http://hgoldfish.com/blogs/article/64/。
想在2.6版本尽量利用3.0的特性,要求写出的代码尽可能地在3.0版本下也可用,或者只要稍微改动就可以。目前我想到的几个点:
使用3.0的print()
函数。
在py2.6里可以简单使用print的函数形式:
#这样可以,但是这毕竟不是函数,任何其它形式都会报错,比如: print("fish is here") #报错,print仍然是一个语句,而不是函数 print("fish is here", file=sys.stderr)
只要在程序最开始的地方加上:
from __future__ import print_function
就OK了
以3.0的形式写字符串,不加任何前缀即是unicode
字符串,加前缀"b"是bytes
类型
py3k重命令了字符串类型,并且改动了它们的记法。括号内是python的版本。重命令的类型:
str(2.6) => bytes(3.0) unicode(2.6) => str(3.0)
改动的字符串记法:
"fish is here"(2.6) => b"fish is here"(3.0) u"fish is here"(2.6) => "fish is here"(3.0)
为了在py2.6程序里使用py3k的写法,可以在程序最开始的地方加上:
from __future__ import unicode_literals
碰到需要bytes
的地方注意加b
前缀。貌似在2.6版本里,struct.pack()
第一个参数不能是unicode
,这应该是个BUG。另外,包(package)的__init__.py
里,__all__
列表的元素必须是bytes
类型,不知道这是BUG还是特性(2.6里测试是这样的)。
有时候需要判断字符串的类型,看看它到底是unicode
字符串还是bytes
类型。因为在py3k里没有unicode
类型,所以在2.6里要:
try: str=unicode except NameError: pass if isinstance(s, str): #unicode字符串 pass #blahblah
使用3.0的io
库。io
库提供了一个更合理的file
类型。在py2.6代码里使用io.open()
来代替open()
。
使用io.BytesIO()
来代替StringIO.StringIO()
。
不使用old-style class的特性。只要重载了__attribute__()
之类的特殊方法,就要考虑是否应该继承自object
所有异常继承自BaseException
注意/
与//
的差别
from __future__ import division
捕获异常到某个变量,使用as关键字
#在py3k里错误,在py2.6里不好的写法 try: raise Exception except Exception, e: pass #良好的写法 try: raise Exception except Exception as e: pass
捕获多种类型的异常
try: io.open(filename,"wb").write(b"haha") except (IOError, OSError): pass
我自己经常搞错,呵呵。不能写成:
try: io.open(filename, "wb").write(b"haha") except IOError, OSError: pass
这种写法在py2.6里面是指捕获IOError
类型的异常,并赋值给OSError
这个变量。
py3k里没有xrange()
函数,可以统一用range()
,或者
try: range=xrange except NameError: pass
py3k对很多本来返回list
的函数进行了处理。原本在py2.x里返回list
对象的函数,现在可能返回的是只支持迭代操作的对象。比如dict.keys()
现在返回的是一个dict_keys
类型的对象。
>>> d={"fish":26} >>> d.keys() dict_keys(['fish']) >>> d.keys()[0] Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'dict_keys' object does not support indexing
想要像以前那样子操作它,最简单的办法是:
>>> list(d.keys())[0] 'fish'
如果编写了某些类似于模拟dict.items()
, dict.keys()
, dict.values()
的函数,比如:
def items(): return [("id", self.id)]+self.value.items()
现在要改写成:
def items(): yield ("id", self.id) for item in self.value.items(): yield item
迭代子(iterator)的next()
函数在py3k里被改成了__next__()
,可以使用内置的next()
函数
next(itor)
相当于itor.next()
或者itor.__next__()
绑定对象的im_self
函数现在是__self__
。im_func
改名__func__
有些模块的名字已经改了,在import的时候要注意:
try: import xmlrpclib except ImportError: import xmlrpc.client
被改名的模块:
_winreg winreg ConfigParser configparser copy_reg copyreg Queue queue SocketServer socketserver markupbase _markupbase repr reprlib test.test_support test.support
被重新归类的模块:
dbm (anydbm, dbhash, dbm, dumbdbm, gdbm, whichdb). html (HTMLParser, htmlentitydefs). http (httplib, BaseHTTPServer, CGIHTTPServer, SimpleHTTPServer, Cookie, cookielib). tkinter (all Tkinter-related modules except turtle). urllib (urllib, urllib2, urlparse, robotparse). xmlrpc (xmlrpclib, DocXMLRPCServer, SimpleXMLRPCServer).
更详细的信息应该看一看py3k的"what's new"
标题无“转载”即原创文章,版权所有。转载请注明来源:http://hgoldfish.com/blogs/article/64/。
胡小来(Sept. 18, 2014, 8:04 p.m.)
搜来搜去就您说的靠谱。