python2和3区别笔记
1.输入和输出
-
input函数,python3中仅保留了input函数,来得到一个<class 'str'>的值,而python2中raw_input用来获取字符串,input用来获取数字# python3.x a = input("请输入: ") # 123 print(type(a), a) # <class 'str'> 123 -
print函数 :python3没有了print语句,取而代之的是print()函数# python3.x print ('hello world!')Python中的print是默认换行的,python3中取消自动换行是print('str', end = ' '),在print语句结尾处添加一个逗号,并设置分隔符参数end# python3.x for i in range(3): print(i, end = ' ') # 0 1 2 # 这里以一个空格来代替自动换行 # print i, # python2.x
2.除法运算
-
python2.x特有-
/除法:1 / 2 = 0、1.0 / 2 = 0.5整数相除得整数,完全忽略小数部分;浮点数除法则保留小数部分
-
-
python3.x特有/除法:只会得到浮点数、1 / 2 = 0.5
-
2和3通用
-
//地板除法,会对除法的结果进行一个floor操作、3 // 2 = 1、-1 // 2 = -1地板除法的结果是不大于正常除法的值中最大的整数
-
3.字符串
-
Unicode字符串
python2中普通字符串都是8位ASCII码进行存储的,而Unicode字符串则存储为16位unicode字符串,使用方法是字符串前面加上前缀u# python2.x >>> a = '中文' >>> type(a) <type 'str'> >>> a = u'中文' >>> type(a) <type 'unicode'>python3中,所有字符串都是Unicode字符串(str类型)。因为源码文件默认使用utf-8编码,所以使用中文就更加方便了,也不需要在文件头部写#coding=utf-8了python3删除了 unicode对象
# python3.x >>> 中文 = 'hello world' >>> 中文 'hello world' >>> a = '中文' >>> type(a) <class 'str'>python3中,严格区分文本(str)和二进制数据(bytes),文本总是unicode,是str类型,二进制数据则用bytes类型(python3新增)表示str与bytes的相互转换# python3.x >>> str = 'jack' >>> a = str.encode('utf-8') >>> type(a) <class 'bytes'> >>> b = b'jack' >>> a = b.decode('utf-8') >>> type(a) <class 'str'>- f-string :字面量格式化字符串,python3.6 新增
之前我们习惯用百分号 (%):
# python3.x >>> name = 'Jack' >>> 'Hello %s'% name 'Hello Jack'f-string格式化字符串以f开头,后面跟着字符串,字符串中的表达式用大括号{}包起来,它会将变量或者表达式计算后的值进行替换f-string本质上并不是字符串常量,而是一个在运行时运算求值的表达式
# python3.x >>> name = 'Jack' >>> f'Hello {name}' # 替换变量 'Hello Jack' >>> f'{1+2}' # 使用表达式 '3' >>> arr = {'name': 'Jack', 'age': 25} >>> f"{arr['name']}: {arr['age']}" 'Jack: 25'这样的话就不用再去判断使用
%s,还是%d
4.range()函数
-
python3 range()函数返回的是一个可迭代对象(类型是对象),而不是列表类型。python2 range()函数返回的是列表。# python3.x >>> type(range(3)) <class 'range'> >>> >>> range(3) range(0, 3) -
python3中没有了xrange()函数,也可以说是xrange()改名成了range()。
5.数据类型
-
不等运算符
python2.x中不等于有两种写法 != 和<>python3.x中只有!=一种了 -
数字类型
python3种的int(整型):带正负的整数,不限制大小,可以当作Long类型用python3没有了Long类型
6.True和False
-
python2中True和False是两个全局变量(名字),在数值上分别对应0和1,既然是变量,就可以指向其他对象# python2.x >>> True = 'asdf' >>> print True asdf -
python3将True和False变为两个关键字,无法被重新赋值>>> True = 1 File "<stdin>", line 1 SyntaxError: can't assign to keyword
7.类
python2中的类默认都是 旧式类, 可以通过继承object来变成新式类
python3中的类默认都是 新式类
-
写法不同
python2:# python 2.x class A: # 旧式类 pass class B(object): # 新式类 passpython3:# python 3.x class A: # 新式类 pass -
多继承
新式类:广度优先搜索
主要是为了解决菱形继承所引发的问题,优先查找平级类中的属性,而非object中的属性
旧式类:深度优先搜索
这是一个菱形继承

# python2.x 旧式类 class A: def __init__(self): pass def save(self): print "This is from A" class B(A): def __init__(self): pass class C(A): def __init__(self): pass def save(self): print "This is from C" class D(B,C): def __init__(self): pass fun = D() fun.save() # This is from A# python3.x 新式类 class A(): def __init__(self): pass def save(self): print ("This is from A") class B(A): def __init__(self): pass class C(A): def __init__(self): pass def save(self): print ("This is from C") class D(B,C): def __init__(self): pass fun = D() fun.save() # This is from C
8.2to3–代码转换
2to3是一个Python程序,它可以将Python2.x的源代码转换为合法的Python3.x代码。2to3的支持库 lib2to3 是一个很灵活通用的库,所以还可以编写属于自己的2to3修复器(官方介绍文档)
1.使用 2to3
2to3通常会作为脚本和Python解释器一起安装,你可以在Python根目录的Tools/scripts文件夹下找到它
2to3的基本调用参数是一个需要转换的文件或者目录列表。对于目录,会递归的寻找其中的Python源码。
这里有一个Python2.x的源码文件,example.py:
def greet(name):
print "Hello, {0}!".format(name)
print "What's your name?"
name = raw_input()
greet(name)
使用2to3转换为Python3.x版本的代码:
传入-w参数,2to3也可以把需要的修改写回到原文件中(除非转入了 -n 参数,否则会为原始文件创建一个副本 example.py.bak)
python3 2to3.py -w example.py
在转换完成后,example.py看起来是这样的:
def greet(name):
print("Hello, {0}!".format(name))
print("What's your name?")
name = input()
greet(name)
注释和缩进都会在转换过程中保持不变
2.修复器
转换代码的每一个步骤都封装在修复器中,可使用 2to3 -l来列出可用的修复器,每个修复器都可以单独的打开或者关闭
重构的本质是遍历修复器分别对目标代码进行转换
def refactor_tree(self, tree, name):
# 源码 默认遍历 修复器 分别对代码进行重构
# tree 是原代码字符串 转换成的<class 'lib2to3.pytree.Node'>对象
for fixer in chain(self.pre_order, self.post_order):
fixer.start_tree(tree, name)
比如:
-
long
将
long重命名为int -
print
将
print语句转换为prin()函数 -
raw_input
将
raw_input()转换为input() -
等等。。。
默认情况下,2to3 会执行预定义修复器的集合。使用 -f 参数可以明确的置顶需要使用的修复器集合,使用-x 参数则可以明确指定不使用的修复器
python3 2to3.py -f raw_input test.py
打印修复器 raw_input
<lib2to3.fixes.fix_raw_input.FixRawInput object at 0x034645D0>
修复器对语法树进行转换后形成新的语法树,再变为字符串
本文详细介绍了从Python2迁移到Python3的关键变化,包括输入输出、除法运算、字符串处理、range()函数、数据类型等方面的差异,并提供了2to3工具的使用方法。
158





