Table of Contents
Python3.0
简单的变化
-
Print Is A Function
print
现在是一个function
而不是一个关键字了, 对于这个变化我只能说 ⑥ -
Views And Iterators Instead Of Lists
某些接口的返回值由
List
替换为了View
或Iterators
:字典
dict
的方法dict.keys()
,dict.items()
和dict.values()
现在返回的是View
而不是List
了内置函数
map()
和filter()
现在返回Iterators
而不是返回List
range()
的行为变得和xrange()
一样, 而xrange()
惨遭移除 QAQzip()
现在返回的也是Iterators
了
感觉这些变化适应了就挺好的, 还可以在一定程度上提升
Python
的性能, 就是苦了那些需要兼容Python2
的程序 @_@ -
Ordering Comparisons
-
比较操作符
<
,<=
,>=
和>
现在比较两个无法比较的对象时会引发TypeError
, 比如0 > None
之类的操作。 不包括!=
和==
这两个操作符。Python2
居然可以这样比较…… -
内置函数
builtin.sorted()
和list.sort()
不在支持cmp
参数。让坑过……
-
不在支持
cmp()
和__cmp__()
, 现在使用__lt__()
进行排序,__eq__()
和__hash__()
用于比较。这个没啥存在感 @_@
-
-
Text Vs. Data Instead Of Unicode Vs. 8-bit
老话题了,
byte
变成了unicode
, 不过用起来感觉不错
语法的变化
新语法
-
PEP 3107 – Function Annotations
现在函数的参数和返回值都可以有注释了, 但是貌似没看到有人用, 有兴趣的可以了解一下:
def compile(source: "something compilable",
filename: "where the compilable thing comes from",
mode: "is this a single statement or a suite?"):
... def haul(item: Haulable, *vargs: PackAnimal) -> Distance:
... -
PEP 3102 – Keyword-Only Arguments
def compare(a, b, *ignore, key=None):
if ignore: # If ignore is not empty
raise TypeError类似上面代码的代码现在可以用如下方式代替:
def compare(a, b, *, key=None):
... -
PEP 3104 – Access to Names in Outer Scopes
新的关键字
nonlocal
, 可以声明一个变量不是本地变量, 具体使用可以去看文档。 -
PEP 3132 – Extended Iterable Unpacking
扩展的可迭代包, 原来这样的语法是
3.0
出来的:(a, *rest, b) = range(5)
其实感觉用的也不多, 但是确实是一个很不错的特性
-
字典推导式 的正确证明, 莫非当初只是提出了
PEP 274
但一时没实现 ?反正感觉编写文档的作者挺高兴的 <_<
-
集合字面值
也就是说类似下面的字面值表示一个集合:
{1, 2}
同时, 集合推导式 也自然而然的出现了:
{x for x in stuff}
-
新的八进制字面值
类似
0o720
的数字代表八进制数字, 早在2.6
就有了 -
新的二进制字面值
类似
0b1010
的数字代表二进制数字, 也是2.6
就有了, 同时新增内置函数bin()
-
字节字符串
现在使用前导字符
b
或B
来表示一个字节字符串:b'123456'
同时, 新增内置函数
bytes()
改动的语法
-
新的
raise
语法raise [expr [from expr]]
额, 感觉没人用的样子
这些东西现在是保留字:
True
,False
,None
,with
,as
-
PEP 3110 – Catching Exceptions in Python 3000
就是这个:
try:
try_body
except E, N:
except_body变成了:
try:
try_body
except E as N:
except_body -
PEP 3115 – Metaclasses in Python 3000
元类的指定方式变了:
# Python2
class C:
__metaclass__ = M
... # Python3
class C(metaclass=M):
...贼坑, 如果要兼容可以使用
with_metaclass
剩下的变化
这次的整理主要是了解一些新特性和常用的变化, 对于哪些说出去基本没人知道的特性的变化还是算了吧……
因此, 剩下的变化我选择省略, 如果你有兴趣的话, 可以到 官方文档 了解一波。
另外, 这里有一个很有趣的事情:
Python 3.6.2 (v3.6.2:5fd33b5, Jul 8 2017, 04:14:34) [MSC v.1900 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> "%s" % 123456
'123456'
@_@
Python3.1
相对 3.0
来说, 3.1
的变化不是很多, 简单来看看。
-
PEP 372 – Adding an ordered dictionary to collections
In [1]: from collections import OrderedDict In [2]: d = OrderedDict() In [3]: d['parrot'] = 'dead' In [4]: d['penguin'] = 'exploded' In [5]: d.items()
Out[5]: odict_items([('parrot', 'dead'), ('penguin', 'exploded')])有序字典, 这个在一些需要保持原有顺序的地方很有用。
-
PEP 378: Format Specifier for Thousands Separator
In [1]: format(1234567, ',d')
Out[1]: '1,234,567' In [2]: format(1234567.89, ',.2f')
Out[2]: '1,234,567.89' In [3]: format(12345.6 + 8901234.12j, ',f')
Out[3]: '12,345.600000+8,901,234.120000j'都快忘记有
format
这个内置函数了 QAQ感觉这个特性还是挺好的, 用到的时候可以省不少劲。
-
new method bitlength() for int type
>>> n = 37
>>> bin(n)
'0b100101'
>>> n.bit_length()
6
虽然还有一些其他的变化, 但我觉得剩下的变化简单了解一下就好, 就不列出来了。
Python3.2
和 3.1
一样, 变换不是很多, 简单看一下就好。
-
PEP 3147: PYC Repository Directories
新的缓存机制, 以前的缓存方案为
.pyc
文件, 但是这个方案在安装了多个Python
的机器上
运行的不太好。于是现在更换的缓存机制, 将缓存保存在了
__pycache__
目录中, 同时根据Python
版本命名缓存文件。目录
__pycache__
基本上一出现我就直接删除了 QAQ -
new start option -q
使用
Python -q
启动解释器可以不显示版本信息, 感觉对我来说暂时没啥用。 -
range objects now support index and count methods
>>> range(0, 100, 2).count(10)
1
>>> range(0, 100, 2).index(10)
5
>>> range(0, 100, 2)[5]
10
>>> range(0, 100, 2)[0:5]
range(0, 10, 2)我觉得这是一个很棒的特性 ( ̄▽ ̄)/
-
The callable() builtin function from Py2.x was resurrected
什么,
callable()
GG 过 !!!∑(゚Д゚ノ)ノ
剩下的变化主要是关于内置模块和低层接口的, 这些东西还是在实践中看相关的文档好了。
Python3.3
和前面两个版本一样, 核心的语法变化不是很多, 简单来看一下就好。
-
PEP 397 – Python launcher for Windows
如果你的操作系统是
Windows
, 并且安装了不止一个版本的Python
, 那么这个特性应该不陌生。通过如下的指令来启动指定版本的
Python
解释器:py -2.7
py -3.6 -
PEP 380 – Syntax for Delegating to a Subgenerator
我觉的这是个好东西, 通过文档中的一个例子来看:
>>> def g(x):
... yield from range(x, 0, -1)
... yield from range(x)
...
>>> list(g(5))
[5, 4, 3, 2, 1, 0, 1, 2, 3, 4]这个很爽啊, 又可以少写几行代码 @_@
-
PEP 409 – Suppressing exception context
这个特性可以让异常的输出更加清楚 ?
>>> class D:
... def __init__(self, extra):
... self._extra_attributes = extra
... def __getattr__(self, attr):
... try:
... return self._extra_attributes[attr]
... except KeyError:
... raise AttributeError(attr) from None
...
>>> D({}).x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 8, in __getattr__
AttributeError: x关键点在
from None
上, 没有这个from None
的话, 抛出的异常会是这样的:Traceback (most recent call last):
File "<stdin>", line 6, in __getattr__
KeyError: 'x' During handling of the above exception, another exception occurred: Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 8, in __getattr__
AttributeError: x -
PEP 414 – Explicit Unicode Literal for Python 3.3
这个特性运行在
Python3
的版本环境中使用u
前缀显示的声明unicode
字符串:u'text'
U'text'虽然已经习惯了, 但还是想吐槽
2 -> 3
的版本变化是真的阔怕…… -
PEP 3155 – Qualified name for classes and functions
函数和类对象的新属性:
__qualname__
, 效果看代码:>>> class C:
... class D:
... def meth(self):
... pass
...
>>> C.D.__name__
'D'
>>> C.D.__qualname__
'C.D'
>>> C.D.meth.__name__
'meth'
>>> C.D.meth.__qualname__
'C.D.meth'
Python3.4
这个版本的文档结构比前面几个版本清楚多了, 简单看一下新特性。
-
PEP 453 – Explicit bootstrapping of pip in Python installations
这个特性很好, 很
nice
, 现在你可以通过这样的命令来安装pip
了:python -m ensurepip
之前我的
pip
因为一天命令 GG, 也因为一条指令还原 QAQ
emmmm, 剩下的变化对我们写代码的影响不大, 省略。
Python3.5
-
PEP 492 – Coroutines with async and await syntax
针对 协程 的新关键字
async
和await
, 官网的例子:import asyncio async def coro(name, lock):
print('coro {}: waiting for lock'.format(name))
async with lock:
print('coro {}: holding the lock'.format(name))
await asyncio.sleep(1)
print('coro {}: releasing the lock'.format(name)) loop = asyncio.get_event_loop()
lock = asyncio.Lock()
coros = asyncio.gather(coro(1, lock), coro(2, lock))
try:
loop.run_until_complete(coros)
finally:
loop.close() # results
coro 2: waiting for lock
coro 2: holding the lock
coro 1: waiting for lock
coro 2: releasing the lock
coro 1: holding the lock
coro 1: releasing the lock我觉得这是一个很重要的新特性, 目前在
Github
上已经可以看到一些只针对高版本Python
开发的库,
其中就用到了这一特性。当然了, 目前我对协程的了解并不多, 因此也更应该去了解。 嗯, 现在知道这么一个特性了。
-
PEP 465 – A dedicated infix operator for matrix multiplication
这应该算是语言的应用场景反过来影响语法开发的一个实例吧, 针对 矩阵运算 的操作符
@
.>>> import numpy >>> x = numpy.ones(3)
>>> x
array([ 1., 1., 1.]) >>> m = numpy.eye(3)
>>> m
array([[ 1., 0., 0.],
[ 0., 1., 0.],
[ 0., 0., 1.]]) >>> x @ m
array([ 1., 1., 1.])这些东西都没用过, 不做评价。 有兴趣的可以了解一下。
-
PEP 448 – Additional Unpacking Generalizations
扩展了
*iterable
和**dictionary
拆包操作符的允许用法, 现在可以在函数中调用任意数量的拆包:>>> print(*[1], *[2], 3, *[4, 5])
1 2 3 4 5 >>> def fn(a, b, c, d):
... print(a, b, c, d)
... >>> fn(**{'a': 1, 'c': 3}, **{'b': 2, 'd': 4})
1 2 3 4同时, 元组, 列表, 集合, 字典等允许同时多个解包:
>>> *range(4), 4
(0, 1, 2, 3, 4) >>> [*range(4), 4]
[0, 1, 2, 3, 4] >>> {*range(4), 4, *(5, 6, 7)}
{0, 1, 2, 3, 4, 5, 6, 7} >>> {'x': 1, **{'y': 2}}
{'x': 1, 'y': 2}恐怖如斯 !
-
和这个特性有关的一个特性: PEP 3107. 我觉得, 只要看了它的表现形式你也应该明白是和什么有关了:
def greeting(name: str) -> str:
return 'Hello ' + name通过注释来表示参数和返回值的类型。
效果:
>>> def greeting(name: str) -> str:
... return 'Hello ' + name
...
>>> greeting(10)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in greeting
TypeError: must be str, not int感觉
Python
代码长得越来越奇怪了 QAQ
Python3.6
-
PEP 498 – Literal String Interpolation
现在我学过的脚本语言都会这一套了:
>>> name = "Fred"
>>> f"He said his name is {name}."
'He said his name is Fred.'
>>> width = 10
>>> precision = 4
>>> value = decimal.Decimal("12.34567")
>>> f"result: {value:{width}.{precision}}" # nested fields
'result: 12.35'感觉通过
Python
的 名称空间 来实现这个特性还是很方便的, 不知道是不是这样来实现的。 -
PEP 526 – Syntax for Variable Annotations
通过特殊的语法来对变量的类型进行注释:
primes: List[int] = [] captain: str # Note: no initial value! class Starship:
stats: Dict[str, int] = {}其他的注释也可以:
name: 'your name'
但似乎就只有注释的作用 ?
>>> name: str = 10
-
PEP 515 – Underscores in Numeric Literals
通过在数字中添加下划线来提高可读性:
>>> 1_000_000_000_000_000
1000000000000000
>>> 0x_FF_FF_FF_FF
4294967295 -
PEP 525 – Asynchronous Generators
3.5
引入了关键字async
和await
, 但是, 通过async
修饰的函数内部不能在使用yield
, 现在, 这个限制
解除了:async def ticker(delay, to):
"""Yield numbers from 0 to *to* every *delay* seconds."""
for i in range(to):
yield i
await asyncio.sleep(delay)代码更难懂了……
-
PEP 530 – Asynchronous Comprehensions
现在在各种推导式, 生成式中都可以用
async
了:result = [i async for i in aiter() if i % 2]
result = [await fun() for fun in funcs if await condition()] -
PEP 487 – Simpler customisation of class creation
现在可以在不使用元类的情况下自定义子类创建, 通过方法
__init_subclass__
:>>> class QuestBase:
... # this is implicitly a @classmethod (see below for motivation)
... def __init_subclass__(cls, swallow, **kwargs):
... cls.swallow = swallow
... super().__init_subclass__(**kwargs) >>> class Quest(QuestBase, swallow="african"):
... pass >>> Quest.swallow
'african' -
PEP 487 – Simpler customisation of class creation
PEP 487
除了前面那个特性以外, 还增强了 描述器 协议 (ノ`Д)ノclass IntField:
def __get__(self, instance, owner):
return instance.__dict__[self.name] def __set__(self, instance, value):
if not isinstance(value, int):
raise ValueError(f'expecting integer in {self.name}')
instance.__dict__[self.name] = value # this is the new initializer:
def __set_name__(self, owner, name):
self.name = name class Model:
int_field = IntField()__set_name__
这个方法会在描述器定义时自动定义,owner
是这个描述器的拥有者,name
则是
描述器在owner
中的名称。在上述例子中,
name
就是int_field
. PEP 529: Change Windows filesystem encoding to UTF-8
PEP 528: Change Windows console encoding to UTF-8
-
PEP 520 – Preserving Class Attribute Definition Order
现在类的
__dict__
中的属性顺序和定义顺序保持一致了。 -
PEP 468 – Preserving the order of **kwargs in a function
**kwargs
形式的参数现在会保持传入的顺序:>>> def func(**kwargs):
... print(kwargs)
...
>>> func(a=1, b=2, c=3, ab=4)
{'a': 1, 'b': 2, 'c': 3, 'ab': 4}