写在前面
python2.6之后发布的python3.0(2008年),但是由于3.0并不能向下兼容2.0,所以10年的时候又发布了一个2.7版本,这个版本一直维护到了2020年,很多3.x后来的特性也被加入到了2.7的迭代中
3.10 更清楚的错误消息 异常信息中会给出关于语法错误的更精准信息
结构化模式匹配 提供各种嵌套语法匹配的match
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 class Point : x: int y: int def location (point ): match point: case Point(x=0 , y=0 ): print ("Origin is the point's location." ) case Point(x=0 , y=y): print (f"Y={y} and the point is on the y-axis." ) case Point(x=x, y=0 ): print (f"X={x} and the point is on the x-axis." ) case Point(): print ("The point is located somewhere else on the plane." ) case _: print ("Not a point" ) match points: case []: print ("No points in the list." ) case [Point(0 , 0 )]: print ("The origin is the only point in the list." ) case [Point(x, y)]: print (f"A single point {x} , {y} is in the list." ) case [Point(0 , y1), Point(0 , y2)]: print (f"Two points on the Y axis at {y1} , {y2} are in the list." ) case _: print ("Something else is found in the list." )
类型提示新特性 1 2 3 4 5 def square (number: int | float ) -> int | float : return number ** 2 isinstance (1 , int | str )True
3.9版本 新特性
标注语法中类型优化 不需要再从typing中导入对应的List类型命,直接使用list,==那么list和List的关系是什么呢==
1 2 3 def greet_all (names: list [str ] ) -> None : for name in names: print ("Hello" , name)
新的解析器 基于PEG的解析器替换LL,性能上大致相当,PEG特性更为灵活,3.10中旧的解析器将被移除,另外3.9版本为最后一个提供对Python2兼容的版本
multiprocessing multiprocessing.SimpleQueue
新增close()方法进行显式的关闭
ipaddress 不再支持IPv4地址字符串中存在前缀0,这个正好前两天碰到过,一般对IP地址的校验中认为前缀0是合法的
1 2 3 4 5 6 7 8 9 >>> import ipaddress>>> ipaddress.ip_address('192.168.0.1' )IPv4Address('192.168.0.1' ) >>> ipaddress.ip_address('192.168.0.01' )Traceback (most recent call last): File "<stdin>" , line 1 , in <module> File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/ipaddress.py" , line 54 , in ip_address raise ValueError(f'{address!r} does not appear to be an IPv4 or IPv6 address' ) ValueError: '192.168.0.01' does not appear to be an IPv4 or IPv6 address
3.8版本 ‘:=’ 赋值表达式 表达式内部为变量赋值,以下代码避免len函数被调用两次,出了范围n的变量还在
1 2 if (n := len (a)) > 10 : print (f"List is too long ({n} elements, expected <= 10)" )
更多语言特性
continue语句可以在finally子句中使用
dict 和 dictview 可以使用 reversed()
按插入顺序反向迭代
新增metadata模块,可以用于查询第三方库的元信息
1 2 3 4 5 6 >>> from importlib.metadata import version, requires, files>>> version('requests' )'2.22.0' >>> list (requires('requests' ))['chardet (<3.1.0,>=3.0.2)' ]
3.7版本 延迟的标注求值 对上个版本中变量标注语法的优化
breakpoint() 新增内置函数breakpoint,替换之前的pdb,经过测试此函数功能等效于以前的pdb,主要是pdb写起来有点复杂,做了一个简单的语法替换
import pdb
pdb.set_trace()
breakpoint()
纳秒级的时间函数 time.time()函数返回的浮点数时间精度跟不上现在计算机的时钟精度,所以进行了迭代
基于哈希的pyc文件 可以了解一下pyc文件的作用,和java字节码文件的异同
数据类dataclasses 没用过,看了说明没没懂使用场景 PEP557
1 2 3 4 5 6 7 8 9 @dataclass class InventoryItem : '''Class for keeping track of an item in inventory.''' name: str unit_price: float quantity_on_hand: int = 0 def total_cost (self ) -> float : return self.unit_price * self.quantity_on_hand
SimpleQueue queue新添加了一个SimpleQueue对象,之前在多进程通信里面用了它的Queue对象,可以去了解下新增对象的特性,另外FIFO是先进先出的缩写
3.6版本 格式化字符串 这个东西类似于format,很多人喜欢用这个语法糖
1 2 3 >>> name = "Fred" >>> f"He said his name is {name} ." 'He said his name is Fred.'
对变量类型的注释 通过这个语法,实现了类似于java的类型规范,但这里只是一个注释,也就是说有没有都无所谓,增加可读性
1 2 3 4 5 primes: List [int ] = [] captain: str class Starship : stats: Dict [str , int ] = {}
数字文字中的下划线 增加数据可读性的语法
1 2 3 4 >>> 1_000_000_000_000_000 1000000000000000 >>> 0x_FF_FF_FF_FF 4294967295
异步 1 2 3 4 5 6 7 8 9 10 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) result = [i async for i in aiter() if i % 2 ] result = [await fun() for fun in funcs if await condition()]
3.5版本 使用async和await实现协程 ‘*‘解包功能 *用于解包可迭代对象
**用于解包字典对象
对函数的注释 1 2 def greeting (name: str ) -> str : return 'Hello ' + name
os.scandir() 优化的目录迭代器
1 2 3 for entry in os.scandir(path): if not entry.name.startswith('.' ) and entry.is_file(): print (entry.name)
heapq python里面堆是什么
1 2 3 4 5 >>> import heapq>>> a = ['9' , '777' , '55555' ]>>> b = ['88' , '6666' ]>>> list (heapq.merge(a, b, key=len ))['9' , '88' , '777' , '6666' , '55555' ]
3.4版本 asyncio模块 协程相关的一个模块,协程这个东西应该研究一下
enum 枚举这个东西用得很少,或者对比和Java的枚举有什么区别
selectors 实现高层级高效率的IO复用,之前在socket编程的时候好像有用到,是对select模块的迭代
statistics 一个数学统计函数
tracemalloc 用于内存分配的分析
3.3版本 3.3版本的迭代内容基本都看不懂。。。
虚拟环境 也就是venv模块是在这个版本加入的
3.2版本 添加argparse 这是一个第三方模块,在这个版本被官方采纳,替换了原本的optparse模块
1 2 3 4 5 import argparseparser = argparse.ArgumentParser(description='此脚本运行需要输入必要参数' ) parser.add_argument('--pid' , '-p' , help ='产品ID,必要参数' , required=False ) args = parser.parse_args() prodcut_id = args.pid
基于字典的日志模块配置 之前是不支持这种配置格式的,添加之后方便了很多
1 2 3 4 5 6 logging_config = { "version" : 1 , "disable_existing_loggers" : False ... } logging.config.dictConfig(logging_config)
添加模块concurrent.futures 这个是线程相关的,灵感来自java,哈哈
碎片 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 format (20 , '#o' )'0o24' format (12.34 , '#5.0f' )' 12.' ➜ ~ python3 -q >>> >>> range (0 , 100 , 2 ).count(10 )1 >>> range (0 , 100 , 2 ).index(10 )5 >>> callable (max )True >>> from itertools import accumulate>>> list (accumulate([8 , 2 , 50 ]))[8 , 10 , 60 ] >>> from collections import Counter>>> tally = Counter(dogs=5 , cats=3 )>>> tally -= Counter(dogs=2 , cats=8 )>>> tallyCounter({'dogs' : 3 }) from datetime import datetime, timezone
线程增加障碍点 这个可以详细的了解下
`from threading import Barrier, Thread`
3.1版本 3.x部分早期版本连Docker都配不出来,所以用python2进行对比
有序字典 1 2 3 4 5 6 7 8 9 10 >>> a = {}>>> a['a' ] = 1 >>> a['b' ] = 2 >>> a['e' ] = 5 >>> a['c' ] = 3 >>> a{'a' : 1 , 'c' : 3 , 'b' : 2 , 'e' : 5 } {'a' : 1 , 'b' : 2 , 'e' : 5 , 'c' : 3 }
这个特性我测试2.7里面已经有了,08年的时候发布了3.0,10年的时候发布的2.7
1 2 >>> 'Sir {} of {}' .format ('Gallahad' , 'Camelot' )'Sir Gallahad of Camelot'
碎片 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 >>> with open ('mylog.txt' ) as infile, open ('a.out' , 'w' ) as outfile:... for line in infile:... if '<critical>' in line:... outfile.write(line)>>> round (1123 , -2 )1100.0 1100 >>> from collections import Counter>>> Counter(['red' , 'blue' , 'red' , 'green' , 'blue' , 'blue' ])Counter({'blue' : 3 , 'red' : 2 , 'green' : 1 })
性能优化
IO库使用C进行重写,有2-20倍速度提升
元组和字典收集机制优化
UTF-8等解码速度提升2-4倍
为JSON模块添加了一个C扩展,大幅改进性能
整数现在存储在内部以 2**15 为基数或以基数存储 2**30(64位计算机上性能提升),以前固定为2**15
3.0版本 print print变成了一个方法
不再返回列表 这个变更主要是为了节省内存,不再直接生成一个列表对象,而是一个可迭代的对象,
而list是对象迭代器,是如何实现的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 >>> a = {'a' : 1 , 'b' : 2 , 'c' : 3 }>>> b = a.keys()>>> b['a' , 'c' , 'b' ] dict_keys(['a' , 'b' , 'c' ]) >>> c = range (10 )>>> c[0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ] range (0 , 10 )>>> def square (x ) :... return x ** 2 ... >>> map (square, [1 ,2 ,3 ,4 ,5 ])[1 , 4 , 9 , 16 , 25 ] <map object at 0x105d682e0 > >>> a = [1 ,2 ,3 ]>>> b = [4 ,5 ,6 ]>>> zipped = zip (a,b)>>> zipped[(1 , 4 ), (2 , 5 ), (3 , 6 )] <zip object at 0x105d5dc40 > >>> zip (*zipped)[(1 , 2 , 3 ), (4 , 5 , 6 )]
整数 将int这么一个极为基础的数据定义进行修改的原因是什么呢,像Java中会有一个整型缓冲池来进行优化,那么Python如何去优化这些极其常用的变量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 >>> type (1 )<type 'int' > >>> type (1000000000000000000000000000000000 )<type 'long' > >>> type (1 )<class 'int' > >>> type (1000000000000000000000000000000000 )<class 'int' > >>> import sys>>> sys.maxint9223372036854775807
小数 离奇
字符集 新语法 1 2 3 4 (a, *rest, b) = range (5 )