悠悠小仙仙 发表于 2017-6-29 16:59:30

Python 2 与 3 不同与兼容

本帖最后由 悠悠小仙仙 于 2017-6-29 17:26 编辑

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



恩,必须加括号了.python 2 里括号是可选的.是作为元祖的显性表示(此句有问题!),而Python 3里 这是函数的括号.Unicode示例代码:

1.import platform
2.print ('Python', platform.python_version())
3.print (type(unicode('this is like a python3 str type')))
4.print (type(b'byte type does not exist'))
5.print ('they are really' + b' the same')
6.print (type(bytearray(b'bytearray oddly does exist though')))
7.print('In python 3 strings are now utf-8 比如中文')
下面是 Python 2 的执行结果:


Python 2.7.10
<type 'unicode'>
<type 'str'>
they are really the same
<type 'bytearray'>
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的执行结果(按行执行):
Python 3.4.3+
Traceback (most recent call last):
File "package/subpackage1/moduleY.py", line 8, in <module>
    print (type(unicode('this is like a python3 str type')))
NameError: name 'unicode' is not defined
<class 'bytes'>
Traceback (most recent call last):
File "package/subpackage1/moduleY.py", line 14, in <module>
    print ('they are really' + b' the same')
TypeError: Can't convert 'bytes' object to str implicitly
<class 'bytearray'>
In python 3 strings are now utf-8 比如中文












试着总结一下,Python 3 里出现了新的类bytes和bytearray,str的编码默认是utf-8.当然也就不再需要Unicode类型了( Python 2 里的情况是默认为ASCII编码,声明u'中文'才是unicode类型.)

悠悠小仙仙 发表于 2017-6-29 16:59:46

本帖最后由 悠悠小仙仙 于 2017-6-29 17:10 编辑

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


def test_range(n):
    a = 0
    for i in range(n):
      a += 1


def test_xrange(n):
    a = 0
    for i in xrange(n):
      a += 1

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

start_time = timeit.default_timer()
test_xrange(n)
print(timeit.default_timer() - start_time)
1
2
3
Python 2.7.10
0.01056599617
0.00666499137878# print 加上括号
Python 3.4.3+
0.007449787999576074
Traceback (most recent call last):
File "package/subpackage1/moduleY.py", line 49, in <module>
    test_xrange(n)
File "package/subpackage1/moduleY.py", line 40, in test_xrange
    for i in xrange(n):
NameError: name 'xrange' is not definedPython 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关键字
import platform

print 'Python', platform.python_version()
try:
    let_us_cause_a_NameError
except NameError, err:
    print err, '--> our error message'
Python 2.7.10
name 'let_us_cause_a_NameError' is not defined --> our error message
import platform

print ('Python', platform.python_version())
try:
    let_us_cause_a_NameError
except NameError as err:
    print (err, '--> our error message')
Python 3.4.3+
name 'let_us_cause_a_NameError' is not defined --> our error message

next()与.next()

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

my_generator = (letter for letter in 'abcdefg')

print (next(my_generator))
print (my_generator.next())

('Python', '2.7.10')
a
b
Python 3.4.3+
a
Traceback (most recent call last):
File "package/subpackage1/moduleY.py", line 12, in <module>
    print (my_generator.next())
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
print ('Python', platform.python_version())

i = 1
print ('before: i =', i)

print ('comprehension: ', )

print ('after: i =', i)
('Python', '2.7.10')
('before: i =', 1)
('comprehension: ', )
('after: i =', 4)
Python 3.4.3+
before: i = 1
comprehension:
after: i = 1比较不可排序类型

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

('Python', '2.7.10')
(" > 'foo' = ", False)
("(1, 2) > 'foo' = ", True)
(' > (1, 2) = ', False)

Python 3.4.3+
Traceback (most recent call last):
File "package/subpackage1/moduleY.py", line 7, in <module>
    print(" > 'foo' = ", > 'foo')
TypeError: unorderable types: list() > str()

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

PEP 3111 – Simple input built-in in Python 3000
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()).
What’s the difference between raw_input() and input() in python3.x?问题问的有点傻,因为python 3里没有raw_input(),但是各位答主生生让这个会负分的问题变成一个热门问题.
python 2里 我们有input()和raw_input(),区别是raw_input()会讲输入返回str.而input()会试图执行输入.
Python 3 里的input()返回字符串,不再有raw_input(),如果想执行输入,可以eval(input())

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

现在在 Python 3 中一些方法和函数返回迭代对象,而不是 Python 2 中的列表
因为通常那些遍历只运行一次,这个改变对节约内存有意义。但是如果遍历多次。它是不那么高效的。这时候,可以用list()包装他.
Some well-known APIs no longer return lists:
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).
Also, the dict.iterkeys(), dict.iteritems() and dict.itervalues() methods are no longer supported.
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).
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))).
range() now behaves like xrange() used to behave, except it works with values of arbitrary size. The latter no longer exists.
zip() now returns an iterator.

兼容
future 模块

用途:在 Python 2 里导入那些在 Python 3 里才生效的模块和函数:
例子:
1
from __future__ import division
下面是一些可被导入的列表:
特性      在此版本可选      在此版本内置      效果
nested_scopes      2.1.0b1      2.2      PEP 227 :静态嵌套作用域
generators      2.2.0a1      2.3      PEP 255 :简单生成器
division      2.2.0a2      3.0      PEP 238 :除法操作符改动
absolute_import      2.5.0a1      3.0      PEP 328: Imports:多行导入与绝对相对路径
with_statement      2.5.0a1      2.6      PEP 343: “with”语句
print_function      2.6.0a2      3.0      PEP 3105 :print语句升级为函数
unicode_literals      2.6.0a2      3.0      PEP 3112: Bytes类型
28.11. __future__ — Future statement definitions参考链接
知乎:Python 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这个是重点..是上面很多东西的源头..建议重点看这个.

jingzizx 发表于 2017-6-29 20:26:49

:victory:

清晨一缕阳光 发表于 2017-6-29 20:51:01

:)
页: [1]
查看完整版本: Python 2 与 3 不同与兼容