- Python 版本分为两大流派:Python 2.x 和 Python 3.x。
- 2020 年 1 月 1 日,Python 官方终止了对 Python 2.7(最后一个 Python 2.x 版本) 的支持,这意味着开发者不会再接收到任何来自 Python 2.7 的错误修复或安全更新。自此 Python 2 完全退休,Python 3 时代正式来临。
- 尽管 Python 2 已退出历史舞台 ,但国内外一些互联网公司仍在使用 Python 2.7 开发程序。
-
- 版本的更换是一项庞大、复杂的工作,一些小型的互联网公司在人力、财力不足的情况下,只能要继续使用低版本的 Python,只有万不得已时才会更新版本。
- 和 Python 2.x 相比,Python 3.x 在语句输出、编码、运算和异常等方面做出了一些调整。
1、Python 3.x print() 函数代替了 print 语句
# Python 2.x 中
print "3, 4"
print(3, 4)
# Python 3.x 中
print(3, 4)
2、Python 3.x 默认使用 UTF-8 编码
- Python 2.x 默认采用的 ASCII 编码;而 Python 3.x 默认使用 UTF-8 编码,可以很好地支持中文或其它非英文字符。
- 示例:使用 Python 2.x 和 Python 3.x 输出一句中文:
[test1@VM-4-13-centos ~]$ python2
Python 2.7.5 (default, Nov 16 2020, 22:23:17)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-44)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> str ="C语言"
>>> str
'C\xe8\xaf\xad\xe8\xa8\x80'
[test1@VM-4-13-centos ~]$ python
Python 3.6.8 (default, Nov 16 2020, 16:55:22)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-44)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> str ="C语言"
>>> str
'C语言'
3、Python 3.x 除法运算
- Python 的除法运算包含 2 个运算符:
/
和//
,这 2 个运算符在 Python 2.x 和 Python 3.x 的使用方法如下:
-
- Python 2.x 中使用
/
进行除法运算的方式和 Java、C 语言类似,整数相除的结果仍是一个整数,浮点数除法会保留小数点部分。 - Python 3.x 中使用
/
运算符,整数之间做除法运算,结果也会是浮点数。 - 使用运算符
//
进行的除法运算叫 floor 除法(“地板除”),即输出不大于结果值的一个最大的整数(向下取整)。此运算符的用法在 Python 2.x 和 Python 3.x 一样。
[test1@VM-4-13-centos ~]$ python2
Python 2.7.5 (default, Nov 16 2020, 22:23:17)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-44)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 1/2
0
>>> 1.0/2
0.5
>>> -1//2
-1
[test1@VM-4-13-centos ~]$ python
Python 3.6.8 (default, Nov 16 2020, 16:55:22)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-44)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 1/2
0.5
>>> -1//2
-1
4、Python 3.x 异常
- Python 3.x 中异常处理改变的地方主要在以下几个方面:
-
- Python 2.x 中,所有类型的对象都是直接被抛出的,但在 Python 3.x 中,只有继承
BaseException
的对象才可以被抛出。 - Python 2.x 中,捕获异常的语法是
except Exception,var:
;但在 Python 3.x 中,引入了as
关键字,捕获异常的语法变更为except Exception as var:
。 - Python 3.x 中,处理异常用
raise Exception(args)
代替了raise Exception,args
。 - Python 3.x 中,取消了异常类的序列行为和
.message
属性。
cat tmp.py
:<<!
#encoding: utf-8
try:
raise TypeError,"类型错误"
except TypeError,err:
print err.message
!
[test1@VM-4-13-centos ~]$ python2 tmp.py
:<<!
类型错误
!
[test1@VM-4-13-centos ~]$ cat tmp.py
:<<!
try:
raise TypeError("类型错误")
except TypeError as err:
print(err)
!
[test1@VM-4-13-centos ~]$ python tmp.py
:<<!
类型错误
!
5、Python 3.x 八进制字面量表示
- Python 3.x 中表示八进制字面量的方式只有一种,并且必须写成
0o1000
,原来01000
的方式不能使用。
[test1@VM-4-13-centos ~]$ python2
Python 2.7.5 (default, Nov 16 2020, 22:23:17)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-44)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 0o1000
512
>>> 01000
512
[test1@VM-4-13-centos ~]$ python
Python 3.6.8 (default, Nov 16 2020, 16:55:22)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-44)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 01000
File "<stdin>", line 1
01000
^
SyntaxError: invalid token
>>> 0o1000
512
6、Python 3.x 不等于运算符
- Python 2.x 中的不等于运算符有 2 种写法:
!=
和<>
,但 Python 3.x 中去掉了<>
。
[test1@VM-4-13-centos ~]$ python2
Python 2.7.5 (default, Nov 16 2020, 22:23:17)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-44)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> 1!=2
True
>>> 1<>2
True
[test1@VM-4-13-centos ~]$ python
Python 3.6.8 (default, Nov 16 2020, 16:55:22)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-44)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> 1!=2
True
>>> 1<>2
File "<stdin>", line 1
1<>2
^
SyntaxError: invalid syntax
7、Python 3.x 输入差异
- Python 2.x 中提供两种类型输入函数:
input()
和raw_input()
,前者默认返回的int
整数类型,而后者总是返回str
字符串类型。 - Python 3.x 中只提供了一个输入函数
input()
,该函数的使用方法与raw_input()
相似,总是返回 str 类型。
[test1@VM-4-13-centos ~]$ python2
Python 2.7.5 (default, Nov 16 2020, 22:23:17)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-44)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> a=input("请输出:")
请输出:123
>>> type(a)
<type 'int'>
>>> b=input("请输入")
请输入"C语言"
>>> b
'C\xe8\xaf\xad\xe8\xa8\x80'
>>> type(b)
<type 'str'>
>>> c=raw_input("请输入:")
请输入:123
>>> type(c)
<type 'str'>
[test1@VM-4-13-centos ~]$ python
Python 3.6.8 (default, Nov 16 2020, 16:55:22)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-44)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> d=input("请输入:")
请输入:123
>>> type(d)
<class 'str'>
8、Python 3.x 数据类型
- Python 3.x 中对数据类型也做了改动,如:
-
- 去除
long
类型,只有一种整形int
,但它的行为就像是 Python 2.x 中的long
。 - 新增
bytes
类型,对应 Python 2.x 的八位串。 - 字典的
keys()
、items()
和values()
方法返回迭代器,且iterkeys()
等函数都被废弃,同时去掉dict.has_key()
,改为用in
替代。
[test1@VM-4-13-centos ~]$ python
Python 3.6.8 (default, Nov 16 2020, 16:55:22)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-44)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> b=b'China'
>>> type(b)
<class 'bytes'>
# 字符串对象和 bytes 对象可以使用 .encode() 或者 .decode()方法相互转化
>>> s=b.decode()
>>> s
'China'
>>> b1=s.encode()
>>> b1
b'China'
9、2.x 与 3.x 的选择
-
- 1994 年发布的 Python 1.0 版本(已过时)
- 2000 年发布的 Python 2.0 版本,截止到 2019 年 3 月份,已经更新到 2.7.16
- 2008 年发布的 Python 3.0 版本,截止到 2019 年 3 月份,已经更新到 3.7.3
- 3 个版本中,Python 3.0 是一次重大的升级,为了避免引入历史包袱,Python 3.0 没有考虑与 Python 2.x 的兼容,这也就导致很长时间以来,Python 2.x 的用户不愿意升级到 Python 3.0。
- 因此,将现有应用从 Python 2.x 迁移到 Python 3.x 是一项不小的挑战。虽然有
2to3
(后续会介绍)之类的工具可以进行代码的自动转换,但无法保证转换后的代码 100% 正确。而且,如果不做人工修改的话,转换后的代码性能可能还不如转换前。将现有的复杂代码库迁移到 Python 3.x 上可能需要付出巨大的精力和成本,某些公司无法负担这些成本。 - 据统计,使用 Python 2.x 的开发者仍占 63.7%,而 Python 3.x 的用户占 36.3%(2020 年,如有错误,欢迎纠正)。由此可见,使用 Python 2.x 的用户还是占多数。在 2014 年,Python 创始人宣布,将 Python 2.7 支持时间延长到 2020 。
- 建议选择 Python 3.x 版本。
- 注意:选择 Python 3.x 也不是没有弊端,很多扩展库的发行总是会滞后于 Python 的发行版本,甚至目前还有很多库不支持 Python 3.x。
10、2to3:自动将 Python 2.x 代码转换成 Python3.x 代码
[test1@VM-4-13-centos ~]$ 2to3 -h
Usage: 2to3 [options] file|dir ...
Options:
-h, --help show this help message and exit
-d, --doctests_only Fix up doctests only
-f FIX, --fix=FIX Each FIX specifies a transformation; default: all
-j PROCESSES, --processes=PROCESSES
Run 2to3 concurrently
-x NOFIX, --nofix=NOFIX
Prevent a transformation from being run
-l, --list-fixes List available transformations
-p, --print-function Modify the grammar so that print() is a function
-v, --verbose More verbose logging
--no-diffs Don't show diffs of the refactoring
-w, --write Write back modified files
-n, --nobackups Don't write backups for modified files
-o OUTPUT_DIR, --output-dir=OUTPUT_DIR
Put output files in this directory instead of
overwriting the input files. Requires -n.
-W, --write-unchanged-files
Also write files even if no changes were required
(useful with --output-dir); implies -w.
--add-suffix=ADD_SUFFIX
Append this string to all output filenames. Requires
-n if non-empty. ex: --add-suffix='3' will generate
.py3 files.
- 假设 Python 2.x 代码存储在
/home/jyhuang/demo.py
文件中,依次执行如下命令:
cd /home/jyhuang/
2to3 -w demo.py
- 执行完成后,在
/home/jyhuang/
目录下也会生成一个名为demo.py.bak
的备份文件,demo.py
文件中就变成了符合 Python 3.x 语法要求的程序。