python.36的特性新定义初学者必看课程

一、Python3.6新特性

1、新的格局化字符串办法

<p "="">新的格局化字符串办法,即在一般字符串前增加 f 或 F 前缀,其效果相似于str.format()。比方

name = "red" print(f"He said his name is {name}.") # 'He said his name is red.' 

<p "="">相当于:

print("He said his name is {name}.".format(**locals()))

<p "="">此外,此特性还支撑嵌套字段,比方:

import decimal
width = 10 precision = 4 value = decimal.Decimal("12.34567")
print(f"result: {value:{width}.{precision}}") #'result:  12.35' 

2、变量声明语法

<p "="">能够像下面相同声明一个变量并指定类型:

from typing import List, Dict
 
primes: List[int] = []
captain: str # 此刻没有初始值 class Starship: stats: Dict[str, int] = {}

3、数字的下划线写法

<p "="">答应在数字中运用下划线,以进步多位数字的可读性。

a = 1_000_000_000_000_000 # 1000000000000000 b = 0x_FF_FF_FF_FF # 4294967295 

<p "="">除此之外,字符串格局化也支撑_选项,以打印出更易读的数字字符串:

'{:_}'.format(1000000)     # '1_000_000' '{:_x}'.format(0xFFFFFFFF)   # 'ffff_ffff' 

4、异步生成器

<p "="">在Python3.5中,引进了新的语法 async 和 await 来完成协同程序。可是有个约束,不能在同一个函数体内同时运用 yield 和 await。Python3.6中,这个约束被放开了,答应界说异步生成器:

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)

5、异步解析器

<p "="">答应在列表list、调集set 和字典dict 解析器中运用 async 或 await 语法。

result = [i async for i in aiter() if i % 2]
result = [await fun() for fun in funcs if await condition()] 

6、新增加模块

<p "="">规范库(The Standard Library)中增加了一个新的模块:secrets。该模块用来生成一些安全性更高的随机数,用于办理passwords, account authentication, security tokens, 以及related secrets等数据。

7、其他新特性

<ul "="">

  • 新的 PYTHONMALLOC 环境变量答应开发者设置内存分配器,以及注册debug钩子等。
  • asyncio模块愈加安稳、高效,并且不再是暂时模块,其间的API也都是安稳版的了。
  • typing模块也有了必定改善,并且不再是暂时模块。
  • datetime.strftime 和 date.strftime 开始支撑ISO 8601的时刻标识符%G, %u, %V。
  • hashlib 和 ssl 模块开始支撑OpenSSL1.1.0。
  • hashlib模块开始支撑新的hash算法,比方BLAKE2, SHA-3 和 SHAKE。
  • Windows上的 filesystem 和 console 默许编码改为UTF-8。
  • json模块中的 json.load() 和 json.loads() 函数开始支撑 binary 类型输入。

<p "="">更多内容参考官方文档:What's New In Python 3.6

二、Python3.7新特性

<p "="">Python 3.7于2018年6月27日发布, 包含许多新特性和优化,增添了众多新的类,可用于数据处理、针对脚本编译和废物收集的优化以及更快的异步I/O,首要如下:<ul "="">

  • 用类处理数据时减少样板代码的数据类。
  • 一处或许无法向后兼容的变更涉及处理生成器中的反常。
  • 面向解说器的“开发办法”。
  • 具有纳秒分辨率的时刻目标。
  • 环境中默许运用UTF-8编码的UTF-8办法。
  • 触发调试器的一个新的内置函数。

1、新增内置函数breakpoint()

<p "="">运用该内置函数,相当于经过代码的办法设置了断点,会主动进入Pbd调试办法。<p "="">假设在环境变量中设置PYTHONBREAKPOINT=0会疏忽此函数。并且,pdb 只是众多可用调试器之一,你能够经过设置新的 PYTHONBREAKPOINT 环境变量来配置想要运用的调试器。<p "="">下面有一个简略比方,用户需求输入一个数字,判断它是否和方针数字相同:

"""猜数字游戏""" def guess(target): user_guess = input("请输入你猜的数 >>> ") if user_guess == target: return "你猜对了!" else: return "猜错了" if __name__ == '__main__':
    a = 100 print(guess(a))

不幸的是,即使猜的数和方针数相同,打印的成果也是‘猜错了’,并且没有任何反常或过错信息。

<p "="">为了弄清楚发作了什么,咱们能够刺进一个断点,来调试一下。以往一般经过print大法或许IDE的调试东西,但现在咱们能够运用 breakpoint()

"""猜数字游戏""" def guess(target): user_guess = input("请输入你猜的数 >>> ")
    breakpoint()   //加入这一行 if user_guess == target: return "你猜对了!" else: return "猜错了" if __name__ == '__main__':
    a = 100 print(guess(a))

在 pdb 提示符下,咱们能够调用 locals() 来查看当前的本地效果域的一切变量。(pdb 有很多的命令,你也能够在其间运行正常的Python 句子)

请输入你猜的数 >>> 100
> d:\work\for_test\py3_test\test.py(7)guess()
-> if user_guess == target:
(Pdb) locals()
{'target': 100, 'user_guess': '100'}
(Pdb) type(user_guess)
'str'>

<p "="">搞理解了,target是一个整数,而user_guess 是一个字符串,这儿发作了类型比照过错。

2、类型和注解

<p "="">从 Python 3.5 开始,类型注解就越来越受欢迎。关于那些不熟悉类型提示的人来说,这是一种完全可选的注释代码的办法,以指定变量的类型。<p "="">什么是注解?它们是相关元数据与变量的语法支撑,能够是恣意表达式,在运行时被 Python 核算但被疏忽。注解能够是任何有用的 Python 表达式。<p "="">下面是个比照的比方:

# 不带类型注解 def foo(bar, baz): # 带类型注解 def foo(bar: 'Describe the bar', baz: print('random')) -> 'return thingy': 

<p "="">上面的做法,其实是Python对自身弱类型言语的强化,希望取得必定的类型可靠和健壮度,向Java等言语挨近。<p "="">在 Python 3.5 中,注解的语法取得规范化,尔后,Python 社区广泛运用了注解类型提示。<p "="">可是,注解仅仅是一种开发东西,能够运用 PyCharm 等 IDE 或 Mypy 等第三方东西进行查看,并不是语法层面的约束。<p "="">咱们前面的猜数程序假设增加类型注解,它应该是这样的:

"""猜数字游戏""" def guess(target:str): user_guess:str = input("请输入你猜的数 >>> ")
    breakpoint() if user_guess == target: return "你猜对了!" else: return "猜错了" if __name__ == '__main__':
    a:int = 100 print(guess(a))

PyCharm会给咱们灰色的规范过错提示,但不会给赤色的语法过错提示。

<p "="">用注解作为类型提示时,有两个首要问题:发动功能和前向引证。<ul "="">

  • 在界说时核算很多恣意表达式相当影响发动功能,并且 typing 模块非常慢
  • 你不能用尚未声明的类型来注解

<p "="">typing 模块如此缓慢的部分原因是,开始的设计方针是在不修正中心 CPython 解说器的情况下完成 typing 模块。跟着类型提示变得越来越盛行,这一约束现已被移除,这意味着现在有了对 typing 的中心支撑。<p "="">而关于向前引证,看下面的比方:

class User: def __init__(self, name: str, prev_user: User) -> None: pass 

<p "="">过错在于 User类型还没有被声明,此刻的 prev_user 不能界说为 User 类型。<p "="">为了解决这个问题,Python3.7 将注解的评价进行了推迟。并且,这项改动向后不兼容,需求先导入annotations,只要到Python 4.0后才会成为默许行为。

from __future__ import annotations class User: def __init__(self, name: str, prev_user: User) -> None: pass 

<p "="">或许如下面的比方:

class C: def validate_b(self, obj: B) -> bool: ... class B: ...

3、新增dataclasses模块

<p "="">这个特性或许是 Python3.7今后比较常用的,它有什么效果呢?<p "="">假设咱们需求编写一个下面的类:

from datetime import datetime import dateutil class Article(object): def __init__(self, _id, author_id, title, text, tags=None, 
                 created=datetime.now(), edited=datetime.now()): self._id = _id
    self.author_id = author_id
    self.title = title
    self.text = text
    self.tags = list() if tags is None else tags
    self.created = created
    self.edited = edited if type(self.created) is str:
       self.created = dateutil.parser.parse(self.created) if type(self.edited) is str:
       self.edited = dateutil.parser.parse(self.edited) def __eq__(self, other): if not isinstance(other, self.__class__): return NotImplemented return (self._id, self.author_id) == (other._id, other.author_id) def __lt__(self, other): if not isinstance(other, self.__class__): return NotImplemented return (self._id, self.author_id) < (other._id, other.author_id) def __repr__(self): return '{}(id={}, author_id={}, title={})'.format(
                self.__class__.__name__, self._id, self.author_id, self.title)

很多的初始化特点要界说默许值,或许还需求重写一堆魔法办法,来完成类实例的打印、比较、排序和去重等功能。

<p "="">假设运用dataclasses进行改造,能够写成这个样子:

from dataclasses import dataclass, field from typing import List from datetime import datetime import dateutil @dataclass(order=True)   //留意这儿 class Article(object): _id: int
    author_id: int
    title: str = field(compare=False)
    text: str = field(repr=False, compare=False)
    tags: List[str] = field(default=list(), repr=False, compare=False)
    created: datetime = field(default=datetime.now(), repr=False, compare=False)
    edited: datetime = field(default=datetime.now(), repr=False, compare=False) def __post_init__(self): if type(self.created) is str:
           self.created = dateutil.parser.parse(self.created) if type(self.edited) is str:
           self.edited = dateutil.parser.parse(self.edited)

这使得类不仅容易设置,并且当咱们创立一个实例并打印出来时,它还能够主动生成美丽的字符串。在与其他类实例进行比较时,它也会有恰当的行为。这是因为dataclasses除了帮咱们主动生成 __init__ 办法外,还生成了一些其他特别办法,如 repreq 和 hash 等。

<p "="">Dataclasses 运用字段 field来完供给默许值,手动结构一个 field() 函数能够访问其他选项,然后更改默许值。例如,这儿将 field 中的 default_factory 设置为一个 lambda 函数,该函数提示用户输入其称号。

from dataclasses import dataclass, field class User: name: str = field(default_factory=lambda: input("enter name"))

4、生成器反常处理

<p "="">在Python 3.7中,生成器引发StopIteration反常后,StopIteration反常将被转换成RuntimeError反常,那样它不会悄悄一路影响应用程序的仓库框架。这意味着怎么处理生成器的行为方面不太敏锐的一些程序会在Python 3.7中抛出RuntimeError。在Python 3.6中,这种行为生成一个弃用正告;在Python 3.7中,它将生成一个完好的过错。<p "="">一个简易的办法是运用try/except代码段,在StopIteration传播到生成器的外面捕获它。更好的解决方案是从头考虑怎么构建生成器――比方说,运用return句子来停止生成器,而不是手动引发StopIteration。

5、开发办法

<p "="">Python解说器增加了一个新的命令行开关:-X,让开发人员能够为解说器设置许多初级选项。<p "="">这种运行时的查看机制一般对功能有严重影响,但在调试进程中对开发人员很有用。<p "="">-X 激活的选项包含:<ul "="">

  • asyncio模块的调试办法。这为异步操作供给了更具体的日志记载和反常处理,而反常操作或许很难调试或推理。
  • 面向内存分配器的调试钩子。这关于编写CPython扩展件的那些人很有用。它能够完成更清晰的运行时查看,了解CPython怎么在内部分配内存和开释内存。
  • 启用faulthandler模块,那样发作溃散后,traceback始终转储出去。

6、 高精度时刻函数

<p "="">Python 3.7中一类新的时刻函数返回纳秒精度的时刻值。尽管Python是一种解说型言语,可是Python的中心开发人员维克多•斯廷纳(Victor Stinner)建议报告纳秒精度的时刻。最首要的原因是,在处理转换其他程序(比方数据库)记载的时刻值时,能够防止丢掉精度。<p "="">新的时刻函数运用后缀_ns。比方说,time.process_time()的纳秒版别是time.process_time_ns()。请留意,并非一切的时刻函数都有对应的纳秒版别。

7、其他新特性

<ul "="">

  • 字典现在保持刺进次序。这在 3.6 中是非正式的,但现在成为了官方言语规范。在大多数情况下,一般的 dict 能够替换 collections.OrderedDict。
  • .pyc 文件具有确定性,支撑可重复构建 —— 也就是说,总是为相同的输入文件生成相同的 byte-for-byte 输出。
  • 新增contextvars模块,针对异步使命供给上下文变量。
  • __main__中的代码会显现弃用正告(DeprecationWarning)。
  • 新增UTF-8办法。在Linux/Unix体系,将疏忽体系的locale,运用UTF-8作为默许编码。在非Linux/Unix体系,需求运用-X utf8选项启用UTF-8办法。
  • 答应模块界说__getattr__、__dir__函数,为弃用正告、延迟import子模块等供给便当。
  • 新的线程本地存储C言语API。
  • 更新Unicode数据到11.0。

三、Python3.8新特性

<p "="">Python3.8版别于2019年10月14日发布,以下是 Python 3.8 比较 3.7 的新增特性。

1、海象赋值表达式

<p "="">新的语法 :=,将值赋给一个更大的表达式中的变量。它被亲切地称为 “海象运算符”(walrus operator),因为它长得像海象的眼睛和象牙。<p "="">“海象运算符” 在某些时候能够让你的代码更整洁,比方:<p "="">鄙人面的示例中,赋值表达式能够防止调用 len () 两次:

if (n := len(a)) > 10:	
    print(f"List is too long ({n} elements, expected <= 10)")

<p "="">相似的优点还可体现在正则表达式匹配中需求运用两次匹配目标的情况中,一次检测用于匹配是否发作,另一次用于提取子分组:

discount = 0.0 if (mo := re.search(r'(\d+)% discount', advertisement)):	
    discount = float(mo.group(1)) / 100.0 

此运算符也可用于合作 while 循环核算一个值,来检测循环是否停止,而同一个值又在循环体中再次被运用的情况:

# Loop over fixed length blocks  while (block := f.read(256)) != '':	
    process(block)

或许出现于列表推导式中,在筛选条件中核算一个值,而同一个值又在表达式中需求被运用:

[clean_name.title() for name in names if (clean_name := normalize('NFC', name)) in allowed_names]

<p "="">请尽量将海象运算符的运用约束在清晰的场合中,以下降复杂性并进步可读性。

2、仅限位置形参

<p "="">新增一个函数形参语法 / 用来指明某些函数形参必须运用仅限位置而非关键字参数的办法。<p "="">这种符号语法与经过 help () 所显现的运用 Larry Hastings 的 Argument Clinic 东西符号的 C 函数相同。<p "="">鄙人面的比方中,形参 a 和 b 为仅限位置形参,c 或 d 能够是位置形参或关键字形参,而 e 或 f 要求为关键字形参:

def f(a, b, /, c, d, *, e, f): print(a, b, c, d, e, f)

<p "="">以下是合法的调用:

f(10, 20, 30, d=40, e=50, f=60)

<p "="">可是,以下均为不合法的调用:

f(10, b=20, c=30, d=40, e=50, f=60) # b 不能够是一个关键字参数 f(10, 20, 30, 40, 50, f=60) # e 必须是一个关键字参数 

<p "="">这种符号办法的一个用例是它答应纯 Python 函数完好模拟现有的用 C 代码编写的函数的行为。例如,内置的 pow () 函数不接受关键字参数:

def pow(x, y, z=None, /): "Emulate the built in pow() function" r = x ** y return r if z is None else r%z

<p "="">另一个用例是在不需求形参称号时扫除关键字参数。例如,内置的 len () 函数的签名为 len (obj, /)。这能够扫除如下这种笨拙的调用办法:

len(obj='hello') # The "obj" keyword argument impairs readability 

<p "="">另一个好处是将形参符号为仅限位置形参将答应在未来修正形参名而不会损坏客户的代码。例如,在 statistics 模块中,形参名 dist 在未来或许被修正。这使得以下函数描述成为或许:

def quantiles(dist, /, *, n=4, method='exclusive') ... 

<p "="">因为在 / 左边的形参不会被公开为可用关键字,其他形参名仍可在 **kwargs 中运用:

>>> def f(a, b, /, **kwargs): ...  print(a, b, kwargs)	
... >>> f(10, 20, a=1, b=2, c=3) # a and b are used in two ways  10 20 {'a': 1, 'b': 2, 'c': 3}

<p "="">这极大地简化了需求接受恣意关键字参数的函数和办法的完成。例如,下面是 collections 模块中的代码摘抄:

class Counter(dict): def __init__(self, iterable=None, /, **kwds): # Note "iterable" is a possible keyword argument 

3、f 字符串支撑 =

<p "="">增加 = 说明符用于 f-string。办法为 f'{expr=}' 的 f 字符串将扩展表示为表达式文本,加一个等于号,再加表达式的求值成果。例如:

>>> user = 'eric_idle' >>> member_since = date(1975, 7, 31) >>> f'{user=} {member_since=}' "user='eric_idle' member_since=datetime.date(1975, 7, 31)" 

<p "="">f 字符串格局说明符答应更细致地控制所要显现的表达式成果:

>>> delta = date.today() - member_since >>> f'{user=!s} {delta.days=:,d}' 'user=eric_idle  delta.days=16,075' 

<p "="">= 说明符将输出整个表达式,以便具体演示核算进程:

>>> print(f'{theta=}  {cos(radians(theta))=:.3f}')	
theta=30 cos(radians(theta))=0.866 

4、 typing模块的改善

<p "="">Python是动态类型言语,但能够经过typing模块增加类型提示,以便第三方东西验证Python代码。Python 3.8给typing增加了一些新元素,因而它能够支撑更健壮的查看:<ul "="">

  • final润饰器和Final类型标示标明,被润饰或被标示的目标在任何时候都不应该被重写、继承,也不能被从头赋值。
  • Literal类型将表达式限定为特定的值或值的列表(不必定是同一个类型的值)。
  • TypedDict能够用来创立字典,其特定键的值被约束在一个或多个类型上。留意这些约束仅用于编译时确定值的合法性,而不能在运行时进行约束。

5、多进程同享内存

<p "="">multiprocessing模块新增SharedMemory类,能够在不同的Python进城之间创立同享的内存区域。<p "="">在旧版别的Python中,进程间同享数据只能经过写入文件、经过网络套接字发送,或选用Python的pickle模块进行序列化等办法。同享内存供给了进程间传递数据的更快的办法,然后使得Python的多处理器和多内核编程更有用率。<p "="">同享内存片段能够作为单纯的字节区域来分配,也能够作为不行修正的相似于列表的目标来分配,其间能保存数字类型、字符串、字节目标、None目标等一小部分Python目标。

6、 新版别的pickle协议

<p "="">Python的pickle模块供给了一种序列化和反序列化Python数据结构或实例的办法,能够将字典原样保存下来供今后读取。不同版别的Python支撑的pickle协议不同,而3.8版别的支撑范围更广、更强壮、更有用的序列化。<p "="">Python 3.8引进的第5版pickle协议能够用一种新办法pickle目标,它能支撑Python的缓冲区协议,如bytes、memoryviews或Numpy array等。新的pickle防止了许多在pickle这些目标时的内存仿制操作。<p "="">NumPy、Apache Arrow等外部库在各自的Python绑定中支撑新的pickle协议。新的pickle也能够作为Python 3.6和3.7的插件运用,能够从PyPI上装置。

7、功能改善

<ul "="">

  • 许多内置办法和函数的速度都进步了20%~50%,因为之前许多函数都需求进行不必要的参数转换。
  • 一个新的opcode缓存能够进步解说器中特定指令的速度。可是,现在完成了速度改善的只要LOAD_GLOBAL opcode,其速度进步了40%。今后的版别中也会进行相似的优化。
  • 文件仿制操作如shutil.copyfile()和shutil.copytree()现在运用平台特定的调用和其他优化办法,来进步操作速度。
  • 新创立的列表现在均匀比曾经小了12%,这要归功于列表结构函数假设能提前知道列表长度的情况下,能够进行优化。
  • Python 3.8中向新式类(如class A(object))的类变量中的写入操作变得更快。operator.itemgetter()和collections.namedtuple()也得到了速度优化。

本文转载于:https://blog.csdn.net/dafengit/article/details/106073709

posted @ 2020-05-12 15:36  ITPS  阅读(321)  评论(0编辑  收藏  举报