Python2 vs 3 差异收集

2017-11-09  本文已影响66人  半夕蝶梦

__ future __ 模块

python3引入了一些python2不兼容的关键字和特性,但是可以用future模块在python2中使用python3的支持。 例如 from __ future__ import print
会导入python3的print_function
再按Python2的语法写print语句就会报错了。

feature optional in mandatory effect
nested_scopes 2.1.0b1 PEP 227: Statically Nested Scopes
generators 2.2.0a1 2.3 PEP 255: Simple Generators
division 2.2.0a2 3.0 PEP 238: Changing the Division Operator
absolute_import 2.5.0a1 3.0 PEP 328: Imports: Multi-Line and Absolute/Relative
with_statement 2.5.0a1 3.0 PEP 343: The “with” Statement
print_function 2.6.0a2 3.0 PEP 3105: Make print a function
unicode_literals 2.6.0a2 3.0 PEP 3112: Bytes literals in Python 3000

(Source)

其实差别在future模块的支持上已经可以看出来了,下面详细的介绍下

print 函数

print是最常用的语法,所以一般大家都知道。 python2的print可以同时语句使用。 python3则是函数,所以括号必不可少。

### python 2
print 'Hello', 'Python'  # 语句 statement, python作为关键字

print ('Hello, Python!')  #可以加(), 但其实这里会创建元组 tuple, 毕竟print是关键字

print "text", print 'print more text on the same line'

"""
我的笔记本设置的是python3内核,没装2,会报错
SyntaxError: Missing parentheses in call to 'print'
装了的切换成2运行
"""
  File "<ipython-input-6-8150a6f0ebec>", line 2
    print 'Hello', 'Python'  # 语句 statement, python作为关键字
                ^
SyntaxError: Missing parentheses in call to 'print'

# python 3
print('Hello Workd')
print("some text", end='') #去掉末尾换行,用来与下面打印在同一行
print('Python', 'World')
Hello Workd
some textPython World

整数除法

python3的整数实现相比于python2有点变化,内部的数据模型编程了变长的实现,python2内部就用long存储,是不变长的数据结构。更改造成了内部内存管理大的改动,不过这个不重要。

来看看整数除法. python2 中 / 的除法跟C语言是一致的,都是取整。 例如 3/2=1 ,如果2/3=0了,所以有的时候计算百分数的要记得转换成浮点数 float(2)/3。 要不然就会一直是0啊!!!

python 2中还有 // ,一样也是取整。

这样一来有点多余,python3就把/ 变成了' 真除', 跟数学上统一了,再也不用管类型转换了 3/2 = 1.5... 整数/整数也可以变成float了!! 但是为了python2同学们的心理健康,有的时候还是会加上类型转换,毕竟习惯了。

字符串

python2的字符串很坑,因为经常会遇到字符编码不一致,打印出错等问题。
看一下知识点
python 内部用Unicode实现字符串
如果遇到文件存储,字符串输出则需要将Unicode编码成对应的String,所以encode(), decode()的用法是String decode成Unicode, Unicode encode 成String ('Utf-8') , 但是用反了也不会报错,没效果就是了。

哪些地方用unicode,哪些地方用string我都是等报错了再改的,但是惯例是内部数据一贯用unicode, 直到最后输入输出再encode

### python 2.7

print type(unicode('haha'))  #生成unicode
print type(u'另一种写法')     # 生成unicode
print type('haha')   #生成string
print type(b'haha')  #string

# 然后就是互相encode decode 了
### python 3
"""
python 3 以后类型变了变,取消了u'df'的写法, 
"""

print(type("haha"))   # str类型
print(type(b'haha'))  # bytes类型

BytesIO , StringIO vs StringIO cStringIO

unicode and str
ByteIO and StringIO已经集成到内部的io模块了

xrange()

x开头的版本应该都表示生成器,前几天还看到了文件读写的xreadlines()版本,所谓的“lazy evaluation”, 比较省内存.
一个生成器(generator)默认只能遍历一遍, 因为他没有在内存中生成整个list

python3把range升级成了xrange, 所以取消了xrange

#### tip: python3里  __contains__  加速range,整形的比浮点型的运算快很多

x = 10000000

# python3 迭代器
def val_in_range(x, val):
    return val in range(x)
%timeit val_in_range(x, x/2)
%timeit val_in_range(x, x//2)

# python2的迭代器
def val_in_xrange(x,val):
    return val in xrange(x)
%timeit val_in_range(x, x/2)


# 说是添加__contains__ 才有的效果,关注下
304 ms ± 16.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
642 ns ± 29.3 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
347 ms ± 13.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

Exception

Python2 支持 raise IOError, "file error" 和 raise IOError("file error")
Python3只支持后者, 如果要打印,还得加上as err

next

Python3 只支持next()函数 不支持 .next 方法

#
a = ( i for i in "abc")
next(a) #right
a.next() # AttributeError
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-11-eead8b4f9249> in <module>()
      2 a = ( i for i in "abc")
      3 next(a) #right
----> 4 a.next() # AttributeError

AttributeError: 'generator' object has no attribute 'next'

列表表达式

列表表达式的作用域缩小,不再影响外围,

print()'Python', python_version())

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

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

print ('after: i =', i)  # i will be 4 in python 2.7,  still be 1 in python3

input()

Python2.7 input() 返回各自的数据类型 raw_input()始终返回str
Python3 input()直接就返回string了

round()

四舍五入法python3也做了改进,采用现在广泛的用法舍入0.5 。 就是舍成最接近的偶数

例如:

from platform import python_version
print('Python', python_version())
print(round(16.5))

round(17.5)
Python 3.6.2
16
Out[12]:
18

Reference

  1. http://sebastianraschka.com/Articles/2014_python_2_3_key_diff.html
  2. http://lucumr.pocoo.org/2014/5/12/everything-about-unicode/
上一篇下一篇

猜你喜欢

热点阅读