51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

查看: 1426|回复: 3
打印 上一主题 下一主题

[转贴] Python 2 与 3 不同与兼容

[复制链接]

该用户从未签到

跳转到指定楼层
1#
发表于 2017-6-29 16:59:30 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 悠悠小仙仙 于 2017-6-29 17:26 编辑

Python的版本问题可能是绕不过的一道坎,自己之前没想着去总结,总想着慢慢来体会,结果发现…还是不行,面试的时候,还是希望你知道这些.
标题起的有些大,由于是自己看文章 + 自己总结,(行文结构参考了下方的参考链接).错误肯定有,欢迎评论,欢迎指正.
总结完我发现好多都遇到过..可惜面对胡大…他当时感冒…重点是….气场太足了…我什么都没想出来… = = 忧伤…
对了,再次推荐参考文章的最后一篇..这就是源文件啊..
不同Import语句
PEP 0328 – Imports: Multi-Line and Absolute/Relative
PEP-0328 中文翻译 By Lance Van
Changes in import statement python3
Python 包管理以及导入包时候一些问题辨析
我试着总结一下:
存疑….我试了几个网上的例子….和他们说的不一样啊…..
print
PEP 3105 – Make print a function
这个PEP 是我见过的最短的了.基本就是说了标题这句话.
python 3 里 print 是一个函数:
1

  1. <table class="t_table"><tbody><tr><td><font face="inherit"><font style="font-size: 15px">print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)</font></font>
  2. </td></tr></tbody></table>
  3. <table class="t_table"><tbody><tr><td><font face="inherit"><font style="font-size: 15px">1</font></font>
  4. </td><td><font face="inherit"><font style="font-size: 15px">print(a, b, c, file=sys.stderr)</font></font>
  5. </td></tr></tbody></table><div align="left"><font color="rgb(153, 153, 153)"><font style="background-color:rgb(63, 63, 63)"><font face="微软雅黑, HelveticaNeue-Light, " "=""><font style="font-size: 16px">等同于 python 2 里
  6. </font></font></font></font></div><table class="t_table"><tbody><tr><td><font face="inherit"><font style="font-size: 15px">1</font></font>
  7. </td><td><font face="inherit"><font style="font-size: 15px">print >>sys.stderr, a, b, c</font></font>
  8. </td></tr></tbody></table>
复制代码

恩,必须加括号了.python 2 里括号是可选的.是作为元祖的显性表示(此句有问题!),而Python 3里 这是函数的括号.
Unicode
示例代码:
  1. 1.import platform
  2. 2.print ('Python', platform.python_version())
  3. 3.print (type(unicode('this is like a python3 str type')))
  4. 4.print (type(b'byte type does not exist'))
  5. 5.print ('they are really' + b' the same')
  6. 6.print (type(bytearray(b'bytearray oddly does exist though')))
  7. 7.print('In python 3 strings are now utf-8 比如中文')
复制代码
下面是 Python 2 的执行结果:


  1. Python 2.7.10
  2. <type 'unicode'>
  3. <type 'str'>
  4. they are really the same
  5. <type 'bytearray'>
  6. SyntaxError: Non-ASCII character '\xe6' in file subpackage1/moduleY.py on line 20, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details
复制代码


下面是python 3的执行结果(按行执行):
  1. Python 3.4.3+
  2. Traceback (most recent call last):
  3.   File "package/subpackage1/moduleY.py", line 8, in <module>
  4.     print (type(unicode('this is like a python3 str type')))
  5. NameError: name 'unicode' is not defined
  6. <class 'bytes'>
  7. Traceback (most recent call last):
  8.   File "package/subpackage1/moduleY.py", line 14, in <module>
  9.     print ('they are really' + b' the same')
  10. TypeError: Can't convert 'bytes' object to str implicitly
  11. <class 'bytearray'>
  12. In python 3 strings are now utf-8 比如中文
复制代码












试着总结一下,Python 3 里出现了新的类bytes和bytearray,str的编码默认是utf-8.当然也就不再需要Unicode类型了( Python 2 里的情况是默认为ASCII编码,声明u'中文'才是unicode类型.)
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏
回复

使用道具 举报

该用户从未签到

2#
 楼主| 发表于 2017-6-29 16:59:46 | 只看该作者
本帖最后由 悠悠小仙仙 于 2017-6-29 17:10 编辑

整除
# 为使代码能同时在两个版本里运行,所有print都加入了括号
  1. import platform
  2. print('Python', platform.python_version())
  3. print('3 / 2 =', 3 / 2)
  4. print('3 // 2 =', 3 // 2)
  5. print('3 / 2.0 =', 3 / 2.0)
  6. print('3 // 2.0 =', 3 // 2.0)
复制代码
Python 2 执行结果:
  1. ('Python', '2.7.10')
  2. ('3 / 2 =', 1)
  3. ('3 // 2 =', 1)
  4. ('3 / 2.0 =', 1.5)
  5. ('3 // 2.0 =', 1.0)
复制代码
Python 3 执行结果:
  1. Python 3.4.3+
  2. 3 / 2 = 1.5
  3. 3 // 2 = 1
  4. 3 / 2.0 = 1.5
  5. 3 // 2.0 = 1.0
  6. python 3 的更清晰,/表示算数除法,//表示整除.
  7. python 2 的混乱一些,//表示整除与 Python 3 一致. ‘/‘在除数被除数都是整数的情况下退化为整除.
  8. xrange
复制代码
  1. import timeit
  2. import platform
  3. n = 100000


  4. def test_range(n):
  5.     a = 0
  6.     for i in range(n):
  7.         a += 1


  8. def test_xrange(n):
  9.     a = 0
  10.     for i in xrange(n):
  11.         a += 1

  12. print 'Python', platform.python_version()
  13. start_time = timeit.default_timer()
  14. test_range(n)
  15. print(timeit.default_timer() - start_time)

  16. start_time = timeit.default_timer()
  17. test_xrange(n)
  18. print(timeit.default_timer() - start_time)
  19. 1
  20. 2
  21. 3
  22. Python 2.7.10
  23. 0.01056599617
  24. 0.00666499137878
复制代码
# print 加上括号
  1. Python 3.4.3+
  2. 0.007449787999576074
  3. Traceback (most recent call last):
  4.   File "package/subpackage1/moduleY.py", line 49, in <module>
  5.     test_xrange(n)
  6.   File "package/subpackage1/moduleY.py", line 40, in test_xrange
  7.     for i in xrange(n):
  8. NameError: name 'xrange' is not defined
复制代码
Python 2 里的range() 和 xrange() 还是有点区别的. xrange() 更像一个生成器.range()生成的是list.
Python 3 里取消了xrange() 代之以range() 实际上 Python 3 把很多返回为List的改成了itrable.
抛出异常

python 2 里,下面两种写法都可以:
1
2
raise IOError, "file error"
raise IOError("file error")
python 3里 ,只接受下面这种写法:
1
raise IOError("file error")

处理异常

python 3 中强制使用as关键字
  1. import platform

  2. print 'Python', platform.python_version()
  3. try:
  4.     let_us_cause_a_NameError
  5. except NameError, err:
  6.     print err, '--> our error message'
  7. Python 2.7.10
  8. name 'let_us_cause_a_NameError' is not defined --> our error message
  9. import platform

  10. print ('Python', platform.python_version())
  11. try:
  12.     let_us_cause_a_NameError
  13. except NameError as err:
  14.     print (err, '--> our error message')
  15. Python 3.4.3+
  16. name 'let_us_cause_a_NameError' is not defined --> our error message

  17. next()与.next()

  18. Python 3 里没有了.next()方法,只保留了next()函数
  19. import platform
  20. print ('Python', platform.python_version())

  21. my_generator = (letter for letter in 'abcdefg')

  22. print (next(my_generator))
  23. print (my_generator.next())

  24. ('Python', '2.7.10')
  25. a
  26. b
  27. Python 3.4.3+
  28. a
  29. Traceback (most recent call last):
  30.   File "package/subpackage1/moduleY.py", line 12, in <module>
  31.     print (my_generator.next())
  32. AttributeError: 'generator' object has no attribute 'next'
复制代码
For 循环变量和全局命名空间泄漏

List comprehensions no longer support the syntactic form [… for var in item1, item2, …]. Use [… for var in (item1, item2, …)] instead. Also note that list comprehensions have different semantics: they are closer to syntactic sugar for a generator expression inside a list() constructor, and in particular the loop control variables are no longer leaked into the surrounding scope.
在 Python 3.x 中 for 循环变量不会再导致命名空间泄漏。
mport platform
  1. print ('Python', platform.python_version())

  2. i = 1
  3. print ('before: i =', i)

  4. print ('comprehension: ', [i for i in range(5)])

  5. print ('after: i =', i)
  6. ('Python', '2.7.10')
  7. ('before: i =', 1)
  8. ('comprehension: ', [0, 1, 2, 3, 4])
  9. ('after: i =', 4)
  10. Python 3.4.3+
  11. before: i = 1
  12. comprehension:  [0, 1, 2, 3, 4]
  13. after: i = 1
复制代码
比较不可排序类型

这个我之前专门查过,Python 2 里并没有显性规定不可比较类型的比较结果,是解释器做的一个约定俗成的显示.
在Python 3里 这个特性被显性规定,不能比较不可比较类型.会抛出异常.如下所示:
  1. import platform
  2. print('Python', platform.python_version())
  3. print("[1, 2] > 'foo' = ", [1, 2] > 'foo')
  4. print("(1, 2) > 'foo' = ", (1, 2) > 'foo')
  5. print("[1, 2] > (1, 2) = ", [1, 2] > (1, 2))

  6. ('Python', '2.7.10')
  7. ("[1, 2] > 'foo' = ", False)
  8. ("(1, 2) > 'foo' = ", True)
  9. ('[1, 2] > (1, 2) = ', False)

  10. Python 3.4.3+
  11. Traceback (most recent call last):
  12.   File "package/subpackage1/moduleY.py", line 7, in <module>
  13.     print("[1, 2] > 'foo' = ", [1, 2] > 'foo')
  14. TypeError: unorderable types: list() > str()

  15. 通过 input() 解析用户的输入

  16. PEP 3111 – Simple input built-in in Python 3000
  17. raw_input() was renamed to input(). That is, the new input() function reads a line from sys.stdin and returns it with the trailing newline stripped. It raises EOFError if the input is terminated prematurely. To get the old behavior of input(), use eval(input()).
  18. What’s the difference between raw_input() and input() in python3.x?问题问的有点傻,因为python 3里没有raw_input(),但是各位答主生生让这个会负分的问题变成一个热门问题.
  19. python 2里 我们有input()和raw_input(),区别是raw_input()会讲输入返回str.而input()会试图执行输入.
  20. Python 3 里的input()返回字符串,不再有raw_input(),如果想执行输入,可以eval(input())
复制代码

返回可迭代对象,而不是列表

现在在 Python 3 中一些方法和函数返回迭代对象,而不是 Python 2 中的列表
因为通常那些遍历只运行一次,这个改变对节约内存有意义。但是如果遍历多次。它是不那么高效的。这时候,可以用list()包装他.
  1. Some well-known APIs no longer return lists:
  2. dict methods dict.keys(), dict.items() and dict.values() return “views” instead of lists. For example, this no longer works: k = d.keys(); k.sort(). Use k = sorted(d) instead (this works in Python 2.5 too and is just as efficient).
  3. Also, the dict.iterkeys(), dict.iteritems() and dict.itervalues() methods are no longer supported.
  4. map() and filter() return iterators. If you really need a list and the input sequences are all of equal length, a quick fix is to wrap map() in list(), e.g. list(map(…)), but a better fix is often to use a list comprehension (especially when the original code uses lambda), or rewriting the code so it doesn’t need a list at all. Particularly tricky is map() invoked for the side effects of the function; the correct transformation is to use a regular for loop (since creating a list would just be wasteful).
  5. If the input sequences are not of equal length, map() will stop at the termination of the shortest of the sequences. For full compatibility with map() from Python 2.x, also wrap the sequences in itertools.zip_longest(), e.g. map(func,sequences) becomes list(map(func, itertools.zip_longest(sequences))).
  6. range() now behaves like xrange() used to behave, except it works with values of arbitrary size. The latter no longer exists.
  7. zip() now returns an iterator.
复制代码

兼容
future 模块

用途:在 Python 2 里导入那些在 Python 3 里才生效的模块和函数:
例子:
1
from __future__ import division
下面是一些可被导入的列表:
特性        在此版本可选        在此版本内置        效果
  1. nested_scopes        2.1.0b1        2.2        PEP 227 :静态嵌套作用域
  2. generators        2.2.0a1        2.3        PEP 255 :简单生成器
  3. division        2.2.0a2        3.0        PEP 238 :除法操作符改动
  4. absolute_import        2.5.0a1        3.0        PEP 328: Imports:多行导入与绝对相对路径
  5. with_statement        2.5.0a1        2.6        PEP 343: “with”语句
  6. print_function        2.6.0a2        3.0        PEP 3105 :print语句升级为函数
  7. unicode_literals        2.6.0a2        3.0        PEP 3112: Bytes类型
  8. 28.11. __future__ — Future statement definitions
复制代码
参考链接
知乎ython 2 和 Python 3 有哪些主要区别?
Key differences between Python 2.7.x and Python 3.x
对应翻译版本
Python 2.7.x 和 Python 3.x 的主要区别
Python2.x与3??.x版本区别
The key differences between Python 2.7.x and Python 3.x with examples
What’s New In Python 3.0这个是重点..是上面很多东西的源头..建议重点看这个.
回复 支持 反对

使用道具 举报

本版积分规则

关闭

站长推荐上一条 /1 下一条

小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

GMT+8, 2024-5-13 15:59 , Processed in 0.068483 second(s), 22 queries .

Powered by Discuz! X3.2

© 2001-2024 Comsenz Inc.

快速回复 返回顶部 返回列表