python2x和python3x的区别

概述#

原稿地址:使用 2to3 将代码移植到 Python 3

几乎所有的Python 2程序都需要一些修改才能正常地运行在Python 3的环境下。为了简化这个转换过程,Python 3自带了一个叫做2to3的实用脚本(Utility Script),这个脚本会将你的Python 2程序源文件作为输入,然后自动将其转换到Python 3的形式。案例研究:将chardet移植到Python 3(porting chardet to Python 3)描述了如何运行这个脚本,然后展示了一些它不能自动修复的情况。这篇附录描述了它能够自动修复的内容。

print语句#

在Python 2里,print是一个语句。无论你想输出什么,只要将它们放在print关键字后边就可以。在Python 3里,print()是一个函数。就像其他的函数一样,print()需要你将想要输出的东西作为参数传给它。

Notes

Python 2

Python 3

print

print()

print 1

print(1)

print 1,2

print(1,2)

print 1,2,

print(1,2, end=' ')

print >>sys.stderr,1, 2, 3

print(1,2, 3, file=sys.stderr)

  1. 为输出一个空白行,需要调用不带参数的print()
  2. 为输出一个单独的值,需要将这这个值作为print()的一个参数就可以了。
  3. 为输出使用一个空格分隔的两个值,用两个参数调用print()即可。
  4. 这个例子有一些技巧。在Python 2里,如果你使用一个逗号(,)作为print语句的结尾,它将会用空格分隔输出的结果,然后在输出一个尾随的空格(trailing space),而不输出回车(carriage return)。在Python 3里,通过把end=' '作为一个关键字参数传给print()可以实现同样的效果。参数end的默认值为'\n',所以通过重新指定end参数的值,可以取消在末尾输出回车符。
  5. 在Python 2里,你可以通过使用>>pipe_name语法,把输出重定向到一个管道,比如sys.stderr。在Python 3里,你可以通过将管道作为关键字参数file的值传递给print()来完成同样的功能。参数file的默认值为std.stdout,所以重新指定它的值将会使print()输出到一个另外一个管道。

Unicode字符串#

Python 2有两种字符串类型:Unicode字符串和非Unicode字符串。Python 3只有一种类型:Unicode字符串(Unicode strings)

Notes

Python 2

Python 3

u'PapayaWhip'

'PapayaWhip'

ur'PapayaWhip\foo'

r'PapayaWhip\foo'

  1. Python 2里的Unicode字符串在Python 3里即普通字符串,因为在Python 3里字符串总是Unicode形式的。
  2. Unicode原始字符串(raw string)(使用这种字符串,Python不会自动转义反斜线"\")也被替换为普通的字符串,因为在Python 3里,所有原始字符串都是以Unicode编码的。

全局函数unicode()#

Python 2有两个全局函数可以把对象强制转换成字符串:unicode()把对象转换成Unicode字符串,还有str()把对象转换为非Unicode字符串。Python 3只有一种字符串类型,Unicode字符串,所以str()函数即可完成所有的功能。(unicode()函数在Python 3里不再存在了。)

Notes

Python 2

Python 3

 

unicode(anything)

str(anything)

long 长整型#

Python 2有为非浮点数准备的intlong类型。int类型的最大值不能超过sys.maxint,而且这个最大值是平台相关的。可以通过在数字的末尾附上一个L来定义长整型,显然,它比int类型表示的数字范围更大。在Python 3里,只有一种整数类型int,大多数情况下,它很像Python 2里的长整型。由于已经不存在两种类型的整数,所以就没有必要使用特殊的语法去区别他们。

进一步阅读:PEP 237:统一长整型和整型

Notes

Python 2

Python 3

x =1000000000000L

x =1000000000000

x =0xFFFFFFFFFFFFL

x =0xFFFFFFFFFFFF

long(x)

int(x)

type(x)is long

type(x)is int

isinstance(x,long)

isinstance(x,int)

  1. 在Python 2里的十进制长整型在Python 3里被替换为十进制的普通整数。
  2. 在Python 2里的十六进制长整型在Python 3里被替换为十六进制的普通整数。
  3. 在Python 3里,由于长整型已经不存在了,自然原来的long()函数也没有了。为了强制转换一个变量到整型,可以使用int()函数。
  4. 检查一个变量是否是整型,获得它的数据类型,并与一个int类型(不是long)的作比较。
  5. 你也可以使用isinstance()函数来检查数据类型;再强调一次,使用int,而不是long,来检查整数类型。

<> 比较运算符#

Python 2支持<>作为!=的同义词。Python 3只支持!=,不再支持<>了。

Notes

Python 2

Python 3

if x <> y:

if x != y:

if x <> y<> z:

if x != y!= z:

  1. 简单地比较。
  2. 相对复杂的三个值之间的比较。

字典类方法has_key()#

在Python 2里,字典对象的has_key()方法用来测试字典是否包含特定的键(key)。Python 3不再支持这个方法了。你需要使用in运算符

Notes

Python 2

Python 3

a_dictionary.has_key('PapayaWhip')

'PapayaWhip' in a_dictionary

a_dictionary.has_key(x)or a_dictionary.has_key(y)

x in a_dictionaryor y in a_dictionary

a_dictionary.has_key(xor y)

(x or y)in a_dictionary

a_dictionary.has_key(x+ y)

(x + y)in a_dictionary

x + a_dictionary.has_key(y)

x +(y in a_dictionary)

  1. 最简单的形式。
  2. 运算符or的优先级高于运算符in,所以这里不需要添加括号。
  3. 另一方面,出于同样的原因 — or的优先级大于in,这里需要添加括号。(注意:这里的代码与前面那行完全不同。Python会先解释x or y,得到结果x(如果x在布尔上下文里的值是真)或者y。然后Python检查这个结果是不是a_dictionary的一个键。)
  4. 运算符in的优先级大于运算符+,所以代码里的这种形式从技术上说不需要括号,但是2to3还是添加了。
  5. 这种形式一定需要括号,因为in的优先级大于+

返回列表的字典类方法#

在Python 2里,许多字典类方法的返回值是列表。其中最常用方法的有keysitemsvalues。在Python 3里,所有以上方法的返回值改为动态视图(dynamic view)。在一些上下文环境里,这种改变并不会产生影响。如果这些方法的返回值被立即传递给另外一个函数,并且那个函数会遍历整个序列,那么以上方法的返回值是列表或者视图并不会产生什么不同。在另外一些情况下,Python 3的这些改变干系重大。如果你期待一个能被独立寻址元素的列表,那么Python 3的这些改变将会使你的代码卡住(choke),因为视图(view)不支持索引(indexing)。

Notes

Python 2

Python 3

a_dictionary.keys()

list(a_dictionary.keys())

a_dictionary.items()

list(a_dictionary.items())

a_dictionary.iterkeys()

iter(a_dictionary.keys())

[i for iin a_dictionary.iterkeys()]

[i for iin a_dictionary.keys()]

min(a_dictionary.keys())

no change

  1. 使用list()函数将keys()的返回值转换为一个静态列表,出于安全方面的考量,2to3可能会报错。这样的代码是有效的,但是对于使用视图来说,它的效率低一些。你应该检查转换后的代码,看看是否一定需要列表,也许视图也能完成同样的工作。
  2. 这是另外一种视图(关于items()方法的)到列表的转换。2to3values()方法返回值的转换也是一样的。
  3. Python 3里不再支持iterkeys()了。如果必要,使用iter()keys()的返回值转换成为一个迭代器。
  4. 2to3能够识别出iterkeys()方法在列表解析里被使用,然后将它转换为Python 3里的keys()方法(不需要使用额外的iter()去包装其返回值)。这样是可行的,因为视图是可迭代的。
  5. 2to3也能识别出keys()方法的返回值被立即传给另外一个会遍历整个序列的函数,所以也就没有必要先把keys()的返回值转换到一个列表。相反的,min()函数会很乐意遍历视图。这个过程对min()max()sum()list()tuple()set()sorted()any()all()同样有效。

被重命名或者重新组织的模块#

从Python 2到Python 3,标准库里的一些模块已经被重命名了。还有一些相互关联的模块也被组合或者重新组织,以使得这种关联更有逻辑性。

http#

在Python 3里,几个相关的HTTP模块被组合成一个单独的包,即http

Notes

Python 2

Python 3

import httplib

import http.client

import Cookie

import http.cookies

import cookielib

import http.cookiejar

import BaseHTTPServer

import SimpleHTTPServer

import CGIHttpServer

import http.server

  1. http.client模块实现了一个底层的库,可以用来请求HTTP资源,解析HTTP响应。
  2. http.cookies模块提供一个蟒样的(Pythonic)接口来获取通过HTTP头部(HTTP header)Set-Cookie发送的cookies
  3. 常用的流行的浏览器会把cookies以文件形式存放在磁盘上,http.cookiejar模块可以操作这些文件。
  4. http.server模块实现了一个基本的HTTP服务器

urllib#

Python 2有一些用来分析,编码和获取URL的模块,但是这些模块就像老鼠窝一样相互重叠。在Python 3里,这些模块被重构、组合成了一个单独的包,即urllib

Notes

Python 2

Python 3

import urllib

import urllib.request, urllib.parse, urllib.error

import urllib2

import urllib.request, urllib.error

import urlparse

import urllib.parse

import robotparser

import urllib.robotparser

from urllib import FancyURLopener

from urllib import urlencode

from urllib.request import FancyURLopener

from urllib.parse import urlencode

from urllib2 import Request

from urllib2 import HTTPError

from urllib.request import

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值