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): # 新式类 pass
python3
:# 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>
修复器对语法树进行转换后形成新的语法树,再变为字符串