python2.7与python3.10核心差异点及通用适配方法



py2.6与2.7是py2从py3过渡的版本,支持部分py3的特性。


  1. 系统差异
    python2:centos 6-7系统默认支持的python版本
    python3:centos8系统默认支持的python版本
  2. print
    py2中print与py3的print()一样,但py2同样支持print(), 但不能打印多个字符串,否则输出类型是tuple
# python2
print 'Hello'
print 'Hello', 'Guido'
print >> sys.stderr, 'Hello'

# python3
print('Hello')
print('Hello', 'Guido')
print('Hello', file=sys.stderr)

# 适配方法,py2和3都可以存在
from __future__ import print_function	# 必须要是导包的第一个
  1. 文件读取
    Python2中使用file( … ) 或 open(…)
    Python3中只能使用open(…)
  2. 字符串编码
    Python3.x 源码文件默认使用 utf-8 编码。
    Python 3默认将字符串存储为Unicode,而如果Python 2要将字符串存储为Unicode,则要求使用“u”标记字符串。
# 通用适配方法:可以使用“u”来标记Unicode字符串(推荐)
# 或导入如下包,将模块中的所有字符串文字设为 unicode 字符串
from __future__ import unicode_literals    # 要放在开头
  1. 除法运算
    5.1 整数除法(向下舍入)
    py2与py3一致,例如: 3//2 == 1,另外,3.0//2==1.0也一致。
    5.2 “真除法”(浮点除法)
    操作数有至少一个浮点数:py2与py3一致,如:3/2.0=1.5
    操作数全是整数:py2为整数,如:3/2=1;py3为浮点数,如:3/2=1.5
# 适配方法,py2和3都可以存在
from __future__ import division    # 必须要是导包的第一个
assert 3 / 2 == 1.5
  1. xrange
    py3中取消了xrange
    range在Python2中返回列表,而在Python3中返回range可迭代对象
# python2
range(10)  			#输出:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 

# python3
range(10) 			# 输出:range(0, 10)
list(range(10)) 	# 输出:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
  1. 八进制字面量表示
    py3中只能写为0oXXXX,py2除了这种,还可以写成0XXXX
0644     # Python2
0o644    # Python2 and 3
  1. 反引号
`x`      # Python2
repr(x)  # Python2和3
  1. 不等运算符
    Py2中不等于有两种写法 != 和 <>
    Py3中只有!=一种写法
  2. 模块改名

旧名字

新名字

_winreg

winreg

ConfigParser

configparser

copy_reg

copyreg

Queue

queue

SocketServer

socketserver

repr

reprlib

  • StringIO模块被合并到新的io模组内
  • new, md5, gopherlib等模块被删除。
  • httplib, BaseHTTPServer, CGIHTTPServer, SimpleHTTPServer, Cookie, cookielib被合并到http包内。
  • 取消了exec语句,只剩下exec()函数。
  1. 数据类型
  1. Python3中取消了long类型,int的取值范围扩大到之前的long类型范围
# long类型消失适配方法
from builtins import int
bigint = int(1)
  1. dict的.keys() .items 和.values()方法返回迭代器,只能通过循环取值,不能通过索引取值,而python2的iterkeys()等函数都被废弃。同时去掉的还有 dict.has_key(),可以用 in来代替
  2. pyhton3新增了bytes类型
    str由若干个字符组成,以字符为单位进行操作;bytes由若干个字节组成,以字节为单位进行操作。字节串和字符串除了操作的数据单元不同之外,它们支持的所有方法都基本相同。bytes 只是简单地记录内存中的原始数据,至于如何使用这些数据,bytes 并不在意。
    str 对象和 bytes 对象可以使用 .encode() (str -> bytes) 或 .decode() (bytes -> str)方法相互转化
  1. 函数式编程 map/filter/ reduce
    从map、filter等函数变为了类,而且reduce挪到了functools,使用时需要显示导包
    Python2:返回列表,直接创建值,可以通过索引取值
    Python3:返回迭代器,不直接创建值,通过循环,边循环边创建
#适配方法:套一个list
mynewlist = list(map(f, myoldlist))
assert mynewlist == [f(x) for x in myoldlist]
  1. 包与导包
    Python2:文件夹中必须有_ _ init _ .py文件
    Python3:不需要有
    _ init _ _.py文件
# 同一个python模块下:
# Python2 绝对路径导包:
import submodule
# Python 2或3相对路径导包:
from . import submodule
# 适配方法
from __future__ import absolute_import  # 加到文件开头
  1. input
    在Python2中raw_input()和input( ),两个函数都存在,其中区别为:
    1)raw_input():将所有输入作为字符串看待,返回字符串类型
    2)input():只能接收"数字"的输入,在对待纯数字输入时具有自己的特性,它返回所输入的数字的类型(int, float )
    在Python3中去除了raw_input(),仅保留了input()函数,其接收任意任性输入,将所有输入默认为字符串处理,并返回字符串类型。
  2. next()函数和.next()方法
    my_generator = (letter for letter in ‘abcdefg’)
    Python2中可以用 next(my_generator) 和 my_generator.next() 两种方式。
    Python3中只能用 next(my_generator)这种方式,或my_generator.next()方法
  3. 列表推导
    不再支持[n for n in a,b]语法,改为[n for n in (a,b)]或[n for n in [a,b]]
  4. 元类
class BaseForm(object):
    pass

class FormType(type):
    pass
    
# Python2:
class Form(BaseForm):
    __metaclass__ = FormType
    pass
# Python3:
class Form(BaseForm, metaclass=FormType):
    pass
    
# Python2和3通用方法:
from six import with_metaclass / from future.utils import with_metaclass
class Form(with_metaclass(FormType, BaseForm)):
    pass
  1. 异常处理
  1. 抛异常
    Python2中所有类型的对象都是可以被直接抛出的,Python3只有继承自BaseException的对象才可以被抛出。
    StandardError 被Python3废弃,统一使用Exception。
# Python 2:
raise ValueError, "dodgy value"
# Python 2和3:
raise ValueError("dodgy value")
  1. 捕获
# Python 2:
	try:
	    ...
	except ValueError, e:
	    ...
	# Python 2和3:
	try:
	    ...
	except ValueError as e:
	    ...
  1. __unicode__与__str__
    python2中使用 __unicode__, python3中使用__str__。

参考文献
https://python-future.org/compatible_idioms.html#unicode-text-string-literals