欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  后端开发

Python 2 和 Python 3 有哪些主要区别?

程序员文章站 2022-05-16 23:10:29
...

回复内容:

我来更正及评论下.
> 1. print不再是语句,而是函数,比如原来是 print 'abc' 现在是 print('abc')
但是 python2.6+ 可以使用 from __future__ import print_function 来实现相同功能
> 2. 在Python 3中,没有旧式类,只有新式类,也就是说不用再像这样 class Foobar(object): pass 显式地子类化object
但是最好还是加上. 主要区别在于 old-style 是 classtype 类型而 new-style 是 type类型
> 3. 原来1/2(两个整数相除)结果是0,现在是0.5了
python 2.2+ 以上都可以使用 from __future__ import division 实现改特性, 同时注意 // 取代了之前的 / 运算
> 4. 新的字符串格式化方法format取代%
错误, 从 python2.6+ 开始已经在str和unicode中有该方法, 同时 python3依然支持 % 算符
> 6. xrange重命名为range
同时更改的还有一系列内置函数及方法, 都返回迭代器对象, 而不是列表或者 元组, 比如 filter, map, dict.items 等
> 7. !=取代
python2 也很少有人用 所以不算什么修改
> 8. long重命名为int
不完全对, python3 彻底废弃了 long+int 双整数实现的方法, 统一为 int , 支持高精度整数运算.
> 9. except Exception, e变成except (Exception) as e
只有 python2.5 及以下版本不支持该语法. python2.6 是支持的. 不算新东西
> 10. exec变成函数
类似 print() 的变化, 之前是语句.

简单补充下
* 主要是类库的变化, 组织结构变了些. 但功能没变. urlparse - > urllib.parse 这样的变化
* 最核心的变化它没有说, 对 bytes 和 原生 UNICODE 字符串的支持, 删除了 unicode 对象, str 为原生 unicode 字符串, bytes 替代了之前的 str 这个是最核心的.
* 其它... 貌似不怎么重要了. 看到大家都没说,我来补充个很重要的:
import在Python3中默认使用绝对路径导入了,这是因为相对路径的导入是具有歧义的
比如文件夹结构:
  • test/
    • main.py
    • lib/
      • __init__.py
      • some_func.py
      • other_func.py
如果运行的是main.py文件,python会将当前cwd作为PYTHONPATH变量
在main.py中,通过
import lib.some_func
或者
from lib import some_func
在some_func.py中,如果使用import other_func是会报错的,建议使用
from lib import other_func
强行使用相对导入需要from .other_func import *
所以说从Python2迁移到Python3,会看到一个大型项目原有的代码结构是否良好,如果之前你的代码到处都是相对导入。。。啧啧
更详细的参见:PEP 0328 -- Imports: Multi-Line and Absolute/Relative

详细的2to3迁移事项可以参考2to3库的文档:26.6. 2to3 - Automated Python 2 to 3 code translation 能自动迁移的部分就不用人工了呗~ Python 2.7.x 与 Python 3.x 的主要差异,详细介绍了Python 2 和Python 3 的差异,并在里面贴了一些好文章,希望对你有帮助。 Python 2.7.x 和 Python 3.x 的主要区别
  • 使用 __future__ 模块
  • print 函数
  • Integer division
  • Unicode
  • xrange
  • Raising exceptions
  • Handling exceptions
  • next() 函数 和 .next() 方法
  • For 循环变量和全局命名空间泄漏
  • 比较不可排序类型
  • 通过 input() 解析用户的输入
  • 返回可迭代对象,而不是列表

原文地址为
Key differences between Python 2.7.x and Python 3.x

翻译地址为
Python 2.7.x 和 Python 3.x 的主要区别修改 最主要的区别是 Python3 程序可以用中文写

不过搞笑的是,有人说不太会看中文写的程序(原话)。

我想他的意思应该是不太习惯,但仍然很搞笑。想知道他每天照镜子时感觉是否习惯

要是有这么一个变态公司/老板,那就没办法了,拿人手短。 py3比py2更规范和统一一些,倒不是说py2不好,只不过因为历史原因或一开始设计思路问题,变得有些复杂

print的改动,去掉了没必要的关键字,换句话说能用函数的就用函数解决,轻量级语法+丰富的库,不搞特化,exec和!=、也差不多基于同样的思想(但是对于exec来说,有个问题需要确认,下面说)
int和long合并,新老类合并,跟上面一样的原因,统一化,简单说就是如果A能实现B全部的功能,或者B能从A简单构造出来,则B没必要存在了
range,map之类的返回迭代器也是基于同样的理由,要实现py2的range,只需要list(range(...)),但反过来,py2要实现迭代器版本的,就只能增加一个xrange,而无法从range直接得到(range会消耗内存)
字符串改为unicode保存,新增字节串,也是为了顺应时代吧,这条貌似被褒奖得非常多,然而我还是要说,把编码问题搞清楚最重要,搞不清楚的人用什么都有可能出问题,只是概率大小的区别

最后说下exec的问题,因为我不用py3,没深入研究,希望懂的人直接回复,不然我还得装一个研究下。。
py作为动态语言,其作用域的变量的值可以大致看做是用{变量名:值}的形式存放在dict中,事实上global域就是这样,不过函数局部变量比较特殊,是在编译时就确定了数量的,所以可以用数组存放,比如
def f():
a = 1
b = 2
print a + b
其中a和b并不是做成{a:1,b:2}的形式,内部实现是一个数组,大致是[1,2]这样(当然不是list,实际上CPython虚拟机是用一个类似Tuple的对象),然后存取都可以直接用偏移来做,这样执行速度提升很明显,因为绝大多数程序的绝大多数运算,都是在函数内部,这个情况在绝大多数语言中也都是成立的
但如果有exec就有问题了:
def f():
a = 1
exec "b = 2"
print a + b
这样我们可以给局部变量域动态增减变量,编译器无法感知,因为exec执行的字符串可能是动态生成的,编译器无法感知,所以py2对这种情况的做法是,如果一个函数含有exec,则这个函数的局部变量域的访问方式会和正常的函数不一样,改为用类似global域的dict这种形式
所以这就要求编译器感知到一个函数是否含有exec,因此exec作为语言关键字是必要的,如果作为函数,编译器可能很难感知到了,因为py可以把函数赋值给其他名字的变量,或者给原本就有的函数名赋值一个其他函数 我觉得比较给力得两点
  1. 编码问题
  2. async 协程加入
RTFM.

这种事情直接在官网上看就可以了,没必要提个问题。
另附链接:What’s New In Python 3.0 帮楼上补一些
google "python 2 3 区别"
goo.gl/vs1ou 1. print不再是语句,而是函数,比如原来是 print 'abc' 现在是 print('abc')
2. 在Python 3中,没有旧式类,只有新式类,也就是说不用再像这样 class Foobar(object): pass 显式地子类化object
3. 原来1/2(两个整数相除)结果是0,现在是0.5了
4. 新的字符串格式化方法format取代%
5. raw_input重命名为input
6. xrange重命名为range
7. !=取代
8. long重命名为int
9. except Exception, e变成except (Exception) as e
10. exec变成函数

其他还有很多。。。