首页  >  文章  >  后端开发  >  Python 2 和 Python 3 有哪些主要区别?

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

WBOY
WBOY原创
2016-06-06 16:22:461183浏览

回复内容:

我来更正及评论下.
> 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变成函数

其他还有很多。。。
声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn