bool:"],[20,"\n","36:0"],[20," return \"animal\" in sentence"],[20,"\n","36:0"],[20,"sentence_has_animal(\"Donald had a farm without animals\")"],[20,"\n","36:0"],[20,"# True"],[20,"\n","36:0"],[20,"枚举 (3.4+)"],[20,"\n","32:1"],[20," Python 3 中的 Enum 类支持"],[20,"枚举","16:\"https%3A%2F%2Fdocs.python.org%2F3%2Flibrary%2Fenum.html\""],[20,"功能,可以使我们的程序变得更加简洁。 Enum 是一种便捷的变量列表的打包方式,使用该方法能够避免多个变量在代码各处分布,使代码显得杂乱无章。\n\nfrom enum import Enum, auto"],[20,"\n\n","36:0"],[20,"class Monster(Enum):"],[20,"\n","36:0"],[20," ZOMBIE = auto()"],[20,"\n","36:0"],[20," WARRIOR = auto()"],[20,"\n","36:0"],[20," BEAR = auto()"],[20,"\n","36:0"],[20," "],[20,"\n","36:0"],[20,"print(Monster.ZOMBIE)"],[20,"\n","36:0"],[20,"# Monster.ZOMBIE"],[20,"\n","36:0"],[20,"\n枚举是一个符号集合,每个符号都和唯一的变量对应。通过使用枚举,我们可以通过符号标识来比较各个成员,我们还可以对枚举本身进行迭代。"],[20,"\n\n","blockquote:true"],[20,"https://docs.python.org/3/library/enum.html"],[20,"\n","blockquote:true"],[20,"\nfor monster in Monster:"],[20,"\n","36:0"],[20," print(monster)"],[20,"\n","36:0"],[20," "],[20,"\n","36:0"],[20,"# Monster.ZOMBIE"],[20,"\n","36:0"],[20,"# Monster.WARRIOR"],[20,"\n","36:0"],[20,"# Monster.BEAR"],[20,"\n","36:0"],[20,"\n","32:1"],[20,"内置的 LRU 缓存 (3.2+)"],[20,"\n","32:1"],[20,"在现如今使用的硬件和软件中,缓存无所不在。Python 3 通过 "],[20,"lru_cache","16:\"https%3A%2F%2Fdocs.python.org%2F3%2Flibrary%2Ffunctools.html%23functools.lru_cache\""],[20," 来使用 LRU ("],[20,"Least Recently Used","16:\"https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FCache_replacement_policies%23Least_recently_used_(LRU)\""],[20,") 缓存。\n\n下面的代码定义了一个斐波拉契函数,由于该函数的运算需要多次递归,每次递归都会执行相同的工作,因此使用缓存能够加速它的计算。\n\nimport time"],[20,"\n\n","36:0"],[20,"def fib(number: int) -> int:"],[20,"\n","36:0"],[20," if number == 0: return 0"],[20,"\n","36:0"],[20," if number == 1: return 1"],[20,"\n","36:0"],[20," "],[20,"\n","36:0"],[20," return fib(number-1) + fib(number-2)"],[20,"\n","36:0"],[20," "],[20,"\n","36:0"],[20,"start = time.time()"],[20,"\n","36:0"],[20,"fib(40)"],[20,"\n","36:0"],[20,"print(f'Duration: {time.time() - start}s')"],[20,"\n","36:0"],[20,"# Duration: 30.684099674224854s"],[20,"\n","36:0"],[20,"\n我们可以使用 lru_cache 来优化该运算。这种优化极技术称为 "],[20,"memoization","16:\"https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FMemoization\""],[20," ,它能够把执行时间从几秒缩减到几纳秒。\n\nfrom functools import lru_cache"],[20,"\n\n","36:0"],[20,"@lru_cache(maxsize=512)"],[20,"\n","36:0"],[20,"def fib_memoization(number: int) -> int:"],[20,"\n","36:0"],[20," if number == 0: return 0"],[20,"\n","36:0"],[20," if number == 1: return 1"],[20,"\n","36:0"],[20," "],[20,"\n","36:0"],[20," return fib_memoization(number-1) + fib_memoization(number-2)"],[20,"\n","36:0"],[20," "],[20,"\n","36:0"],[20,"start = time.time()"],[20,"\n","36:0"],[20,"fib_memoization(40)"],[20,"\n","36:0"],[20,"print(f'Duration: {time.time() - start}s')"],[20,"\n","36:0"],[20,"# Duration: 6.866455078125e-05s"],[20,"\n","36:0"],[20,"\n","32:1"],[20,"扩展的可迭代解析功能(3.0+)"],[20,"\n","32:1"],[20,"这里不做详细解释,直接贴出示例代码,具体解决可以参考这篇"],[20,"文档","16:\"https%3A%2F%2Fwww.python.org%2Fdev%2Fpeps%2Fpep-3132%2F\""],[20,"。\nhead, *body, tail = range(5)"],[20,"\n","36:0"],[20,"print(head, body, tail)"],[20,"\n","36:0"],[20,"# 0 [1, 2, 3] 4"],[20,"\n\n","36:0"],[20,"py, filename, *cmds = \"python3.7 script.py -n 5 -l 15\".split()"],[20,"\n","36:0"],[20,"print(py)"],[20,"\n","36:0"],[20,"print(filename)"],[20,"\n","36:0"],[20,"print(cmds)"],[20,"\n","36:0"],[20,"# python3.7"],[20,"\n","36:0"],[20,"# script.py"],[20,"\n","36:0"],[20,"# ['-n', '5', '-l', '15']"],[20,"\n\n","36:0"],[20,"first, _, third, *_ = range(10)"],[20,"\n","36:0"],[20,"print(first, third)"],[20,"\n","36:0"],[20,"# 0 2"],[20,"\n","36:0"],[20,"\n","32:1"],[20,"数据类(3.7+)"],[20,"\n","32:1"],[20,"Python 3 引入了数据类 (data class)。其装饰器会自动生成特征方法,例如 __init__() 和 __repr()__,这能够帮助减少样本代码的数量。在官方"],[20,"文档","16:\"https%3A%2F%2Fwww.python.org%2Fdev%2Fpeps%2Fpep-0557%2F\""],[20,"中,它们被称作 “具有默认值的可变命名元组” 。\n\nclass Armor:"],[20,"\n","36:0"],[20," "],[20,"\n","36:0"],[20," def __init__(self, armor: float, description: str, level: int = 1):"],[20,"\n","36:0"],[20," self.armor = armor"],[20,"\n","36:0"],[20," self.level = level"],[20,"\n","36:0"],[20," self.description = description"],[20,"\n","36:0"],[20," "],[20,"\n","36:0"],[20," def power(self) -> float:"],[20,"\n","36:0"],[20," return self.armor * self.level"],[20,"\n","36:0"],[20," "],[20,"\n","36:0"],[20,"armor = Armor(5.2, \"Common armor.\", 2)"],[20,"\n","36:0"],[20,"armor.power()"],[20,"\n","36:0"],[20,"# 10.4"],[20,"\n\n","36:0"],[20,"print(armor)"],[20,"\n","36:0"],[20,"#"],[20,"\n","36:0"],[20,"\n接来下我们使用数据类来实现上面的代码:\n\nfrom dataclasses import dataclass"],[20,"\n\n","36:0"],[20,"@dataclass"],[20,"\n","36:0"],[20,"class Armor:"],[20,"\n","36:0"],[20," armor: float"],[20,"\n","36:0"],[20," description: str"],[20,"\n","36:0"],[20," level: int = 1"],[20,"\n","36:0"],[20," "],[20,"\n","36:0"],[20," def power(self) -> float:"],[20,"\n","36:0"],[20," return self.armor * self.level"],[20,"\n","36:0"],[20," "],[20,"\n","36:0"],[20,"armor = Armor(5.2, \"Common armor.\", 2)"],[20,"\n","36:0"],[20,"armor.power()"],[20,"\n","36:0"],[20,"# 10.4"],[20,"\n\n","36:0"],[20,"print(armor)"],[20,"\n","36:0"],[20,"# Armor(armor=5.2, description='Common armor.', level=2)"],[20,"\n","36:0"],[20,"\n","32:1"],[20,"隐式命名空间包(3.3+)"],[20,"\n","32:1"],[20,"构建Python代码有很多方法,其中一种就是在包(packages)中进行构建(即包含一个 __init__.py 文件的文件夹)。以下示例由 Python 的官方文档提供:\n\nsound/ Top-level package"],[20,"\n","36:0"],[20," __init__.py Initialize the sound package"],[20,"\n","36:0"],[20," formats/ Subpackage for file format conversions"],[20,"\n","36:0"],[20," __init__.py"],[20,"\n","36:0"],[20," wavread.py"],[20,"\n","36:0"],[20," wavwrite.py"],[20,"\n","36:0"],[20," aiffread.py"],[20,"\n","36:0"],[20," aiffwrite.py"],[20,"\n","36:0"],[20," auread.py"],[20,"\n","36:0"],[20," auwrite.py"],[20,"\n","36:0"],[20," ..."],[20,"\n","36:0"],[20," effects/ Subpackage for sound effects"],[20,"\n","36:0"],[20," __init__.py"],[20,"\n","36:0"],[20," echo.py"],[20,"\n","36:0"],[20," surround.py"],[20,"\n","36:0"],[20," reverse.py"],[20,"\n","36:0"],[20," ..."],[20,"\n","36:0"],[20," filters/ Subpackage for filters"],[20,"\n","36:0"],[20," __init__.py"],[20,"\n","36:0"],[20," equalizer.py"],[20,"\n","36:0"],[20," vocoder.py"],[20,"\n","36:0"],[20," karaoke.py"],[20,"\n","36:0"],[20," ..."],[20,"\n","36:0"],[20,"\n"],[20,"在 Python 2 中,上面的每个文件夹都必须有一个 ","0:\"%23333333\""],[20," __init__.py ","31:1"],[20,"文件,该文件用于将其所在文件夹转化为 Python 包。然而在 Python 3 中,通过使用","0:\"%23333333\""],[20,"隐式命名空间包","0:\"%23333333\"|16:\"https%3A%2F%2Fwww.python.org%2Fdev%2Fpeps%2Fpep-0420%2F\""],[20,"(Implicit Namespace Package)"],[20,",这些文件就不再需要了。","0:\"%23333333\""],[20,"\n\nsound/ Top-level package"],[20,"\n","36:0"],[20," __init__.py Initialize the sound package"],[20,"\n","36:0"],[20," formats/ Subpackage for file format conversions"],[20,"\n","36:0"],[20," wavread.py"],[20,"\n","36:0"],[20," wavwrite.py"],[20,"\n","36:0"],[20," aiffread.py"],[20,"\n","36:0"],[20," aiffwrite.py"],[20,"\n","36:0"],[20," auread.py"],[20,"\n","36:0"],[20," auwrite.py"],[20,"\n","36:0"],[20," ..."],[20,"\n","36:0"],[20," effects/ Subpackage for sound effects"],[20,"\n","36:0"],[20," echo.py"],[20,"\n","36:0"],[20," surround.py"],[20,"\n","36:0"],[20," reverse.py"],[20,"\n","36:0"],[20," ..."],[20,"\n","36:0"],[20," filters/ Subpackage for filters"],[20,"\n","36:0"],[20," equalizer.py"],[20,"\n","36:0"],[20," vocoder.py"],[20,"\n","36:0"],[20," karaoke.py"],[20,"\n","36:0"],[20," ..."],[20,"\n","36:0"],[20,"\n注:官方文档"],[20,"PEP 420 Specification","16:\"https%3A%2F%2Fwww.python.org%2Fdev%2Fpeps%2Fpep-0420%2F%23specification\""],[20," 指出,对于一些常规的包,__init__.py 仍然是需要的 ,如果将该文件删除,就会把该 Python 包变成一个本地的命名空间包,这将会产生一些额外的限制,具体可以参考这篇"],[20,"文档","16:\"https%3A%2F%2Fpackaging.python.org%2Fguides%2Fpackaging-namespace-packages%2F%23native-namespace-packages\""],[20,"。\n总结"],[20,"\n","32:1"],[20,"Python3 中的新功能远远不止如此,大家可以进一步进行探索。本文列出的内容只是一些实用的功能,希望能够对大家有所帮助。\n\n文中的代码链接:"],[20,"\n","blockquote:true"],[20,"https://github.com/Weenkus/DataWhatNow-Codes/blob/master/things_you_are_probably_not_using_in_python_3_but_should/python%203%20examples.ipynb"],[20,"\n","blockquote:true"]]">
作者 | Vinko Kodoman
翻译 | Monanfei
编辑 | 阿司匹林,Rachel
【导读】在 python 3 推出后,人们开始逐步将基于Python 2 的代码迁移至 Python 3 。但在迁移过程中,很多代码都未能使用到 Python 3 提供的新功能。本文作者介绍了相关功能的介绍,包括字符串格式化处理、文件路径处理、类型提示、内置 LRU 缓存等等,帮助大家更好地利用 python 3 书写代码。
由于 Python 2 即将退出历史的舞台,许多人都开始将 Python 2 的代码转换为 Python 3 ,但在这一修改过程中,人们似乎只是多加了几个括号,大多数人并没有注意到 Python 3 中激动人心的新功能。本文将介绍 Python 3 中一些有趣的功能,希望这些功能能够帮助大家更加轻松的解决一些问题。
注:文中的代码示例基于 Python 3.7 编写,为方便使用,在每个功能后面都列出了该功能所需的最低 Python 版本。
bool:"],[20,"\n","36:0"],[20," return \"animal\" in sentence"],[20,"\n","36:0"],[20,"sentence_has_animal(\"Donald had a farm without animals\")"],[20,"\n","36:0"],[20,"# True"],[20,"\n","36:0"],[20,"枚举 (3.4+)"],[20,"\n","32:1"],[20," Python 3 中的 Enum 类支持"],[20,"枚举","16:\"https%3A%2F%2Fdocs.python.org%2F3%2Flibrary%2Fenum.html\""],[20,"功能,可以使我们的程序变得更加简洁。 Enum 是一种便捷的变量列表的打包方式,使用该方法能够避免多个变量在代码各处分布,使代码显得杂乱无章。\n\nfrom enum import Enum, auto"],[20,"\n\n","36:0"],[20,"class Monster(Enum):"],[20,"\n","36:0"],[20," ZOMBIE = auto()"],[20,"\n","36:0"],[20," WARRIOR = auto()"],[20,"\n","36:0"],[20," BEAR = auto()"],[20,"\n","36:0"],[20," "],[20,"\n","36:0"],[20,"print(Monster.ZOMBIE)"],[20,"\n","36:0"],[20,"# Monster.ZOMBIE"],[20,"\n","36:0"],[20,"\n枚举是一个符号集合,每个符号都和唯一的变量对应。通过使用枚举,我们可以通过符号标识来比较各个成员,我们还可以对枚举本身进行迭代。"],[20,"\n\n","blockquote:true"],[20,"https://docs.python.org/3/library/enum.html"],[20,"\n","blockquote:true"],[20,"\nfor monster in Monster:"],[20,"\n","36:0"],[20," print(monster)"],[20,"\n","36:0"],[20," "],[20,"\n","36:0"],[20,"# Monster.ZOMBIE"],[20,"\n","36:0"],[20,"# Monster.WARRIOR"],[20,"\n","36:0"],[20,"# Monster.BEAR"],[20,"\n","36:0"],[20,"\n","32:1"],[20,"内置的 LRU 缓存 (3.2+)"],[20,"\n","32:1"],[20,"在现如今使用的硬件和软件中,缓存无所不在。Python 3 通过 "],[20,"lru_cache","16:\"https%3A%2F%2Fdocs.python.org%2F3%2Flibrary%2Ffunctools.html%23functools.lru_cache\""],[20," 来使用 LRU ("],[20,"Least Recently Used","16:\"https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FCache_replacement_policies%23Least_recently_used_(LRU)\""],[20,") 缓存。\n\n下面的代码定义了一个斐波拉契函数,由于该函数的运算需要多次递归,每次递归都会执行相同的工作,因此使用缓存能够加速它的计算。\n\nimport time"],[20,"\n\n","36:0"],[20,"def fib(number: int) -> int:"],[20,"\n","36:0"],[20," if number == 0: return 0"],[20,"\n","36:0"],[20," if number == 1: return 1"],[20,"\n","36:0"],[20," "],[20,"\n","36:0"],[20," return fib(number-1) + fib(number-2)"],[20,"\n","36:0"],[20," "],[20,"\n","36:0"],[20,"start = time.time()"],[20,"\n","36:0"],[20,"fib(40)"],[20,"\n","36:0"],[20,"print(f'Duration: {time.time() - start}s')"],[20,"\n","36:0"],[20,"# Duration: 30.684099674224854s"],[20,"\n","36:0"],[20,"\n我们可以使用 lru_cache 来优化该运算。这种优化极技术称为 "],[20,"memoization","16:\"https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FMemoization\""],[20," ,它能够把执行时间从几秒缩减到几纳秒。\n\nfrom functools import lru_cache"],[20,"\n\n","36:0"],[20,"@lru_cache(maxsize=512)"],[20,"\n","36:0"],[20,"def fib_memoization(number: int) -> int:"],[20,"\n","36:0"],[20," if number == 0: return 0"],[20,"\n","36:0"],[20," if number == 1: return 1"],[20,"\n","36:0"],[20," "],[20,"\n","36:0"],[20," return fib_memoization(number-1) + fib_memoization(number-2)"],[20,"\n","36:0"],[20," "],[20,"\n","36:0"],[20,"start = time.time()"],[20,"\n","36:0"],[20,"fib_memoization(40)"],[20,"\n","36:0"],[20,"print(f'Duration: {time.time() - start}s')"],[20,"\n","36:0"],[20,"# Duration: 6.866455078125e-05s"],[20,"\n","36:0"],[20,"\n","32:1"],[20,"扩展的可迭代解析功能(3.0+)"],[20,"\n","32:1"],[20,"这里不做详细解释,直接贴出示例代码,具体解决可以参考这篇"],[20,"文档","16:\"https%3A%2F%2Fwww.python.org%2Fdev%2Fpeps%2Fpep-3132%2F\""],[20,"。\nhead, *body, tail = range(5)"],[20,"\n","36:0"],[20,"print(head, body, tail)"],[20,"\n","36:0"],[20,"# 0 [1, 2, 3] 4"],[20,"\n\n","36:0"],[20,"py, filename, *cmds = \"python3.7 script.py -n 5 -l 15\".split()"],[20,"\n","36:0"],[20,"print(py)"],[20,"\n","36:0"],[20,"print(filename)"],[20,"\n","36:0"],[20,"print(cmds)"],[20,"\n","36:0"],[20,"# python3.7"],[20,"\n","36:0"],[20,"# script.py"],[20,"\n","36:0"],[20,"# ['-n', '5', '-l', '15']"],[20,"\n\n","36:0"],[20,"first, _, third, *_ = range(10)"],[20,"\n","36:0"],[20,"print(first, third)"],[20,"\n","36:0"],[20,"# 0 2"],[20,"\n","36:0"],[20,"\n","32:1"],[20,"数据类(3.7+)"],[20,"\n","32:1"],[20,"Python 3 引入了数据类 (data class)。其装饰器会自动生成特征方法,例如 __init__() 和 __repr()__,这能够帮助减少样本代码的数量。在官方"],[20,"文档","16:\"https%3A%2F%2Fwww.python.org%2Fdev%2Fpeps%2Fpep-0557%2F\""],[20,"中,它们被称作 “具有默认值的可变命名元组” 。\n\nclass Armor:"],[20,"\n","36:0"],[20," "],[20,"\n","36:0"],[20," def __init__(self, armor: float, description: str, level: int = 1):"],[20,"\n","36:0"],[20," self.armor = armor"],[20,"\n","36:0"],[20," self.level = level"],[20,"\n","36:0"],[20," self.description = description"],[20,"\n","36:0"],[20," "],[20,"\n","36:0"],[20," def power(self) -> float:"],[20,"\n","36:0"],[20," return self.armor * self.level"],[20,"\n","36:0"],[20," "],[20,"\n","36:0"],[20,"armor = Armor(5.2, \"Common armor.\", 2)"],[20,"\n","36:0"],[20,"armor.power()"],[20,"\n","36:0"],[20,"# 10.4"],[20,"\n\n","36:0"],[20,"print(armor)"],[20,"\n","36:0"],[20,"#"],[20,"\n","36:0"],[20,"\n接来下我们使用数据类来实现上面的代码:\n\nfrom dataclasses import dataclass"],[20,"\n\n","36:0"],[20,"@dataclass"],[20,"\n","36:0"],[20,"class Armor:"],[20,"\n","36:0"],[20," armor: float"],[20,"\n","36:0"],[20," description: str"],[20,"\n","36:0"],[20," level: int = 1"],[20,"\n","36:0"],[20," "],[20,"\n","36:0"],[20," def power(self) -> float:"],[20,"\n","36:0"],[20," return self.armor * self.level"],[20,"\n","36:0"],[20," "],[20,"\n","36:0"],[20,"armor = Armor(5.2, \"Common armor.\", 2)"],[20,"\n","36:0"],[20,"armor.power()"],[20,"\n","36:0"],[20,"# 10.4"],[20,"\n\n","36:0"],[20,"print(armor)"],[20,"\n","36:0"],[20,"# Armor(armor=5.2, description='Common armor.', level=2)"],[20,"\n","36:0"],[20,"\n","32:1"],[20,"隐式命名空间包(3.3+)"],[20,"\n","32:1"],[20,"构建Python代码有很多方法,其中一种就是在包(packages)中进行构建(即包含一个 __init__.py 文件的文件夹)。以下示例由 Python 的官方文档提供:\n\nsound/ Top-level package"],[20,"\n","36:0"],[20," __init__.py Initialize the sound package"],[20,"\n","36:0"],[20," formats/ Subpackage for file format conversions"],[20,"\n","36:0"],[20," __init__.py"],[20,"\n","36:0"],[20," wavread.py"],[20,"\n","36:0"],[20," wavwrite.py"],[20,"\n","36:0"],[20," aiffread.py"],[20,"\n","36:0"],[20," aiffwrite.py"],[20,"\n","36:0"],[20," auread.py"],[20,"\n","36:0"],[20," auwrite.py"],[20,"\n","36:0"],[20," ..."],[20,"\n","36:0"],[20," effects/ Subpackage for sound effects"],[20,"\n","36:0"],[20," __init__.py"],[20,"\n","36:0"],[20," echo.py"],[20,"\n","36:0"],[20," surround.py"],[20,"\n","36:0"],[20," reverse.py"],[20,"\n","36:0"],[20," ..."],[20,"\n","36:0"],[20," filters/ Subpackage for filters"],[20,"\n","36:0"],[20," __init__.py"],[20,"\n","36:0"],[20," equalizer.py"],[20,"\n","36:0"],[20," vocoder.py"],[20,"\n","36:0"],[20," karaoke.py"],[20,"\n","36:0"],[20," ..."],[20,"\n","36:0"],[20,"\n"],[20,"在 Python 2 中,上面的每个文件夹都必须有一个 ","0:\"%23333333\""],[20," __init__.py ","31:1"],[20,"文件,该文件用于将其所在文件夹转化为 Python 包。然而在 Python 3 中,通过使用","0:\"%23333333\""],[20,"隐式命名空间包","0:\"%23333333\"|16:\"https%3A%2F%2Fwww.python.org%2Fdev%2Fpeps%2Fpep-0420%2F\""],[20,"(Implicit Namespace Package)"],[20,",这些文件就不再需要了。","0:\"%23333333\""],[20,"\n\nsound/ Top-level package"],[20,"\n","36:0"],[20," __init__.py Initialize the sound package"],[20,"\n","36:0"],[20," formats/ Subpackage for file format conversions"],[20,"\n","36:0"],[20," wavread.py"],[20,"\n","36:0"],[20," wavwrite.py"],[20,"\n","36:0"],[20," aiffread.py"],[20,"\n","36:0"],[20," aiffwrite.py"],[20,"\n","36:0"],[20," auread.py"],[20,"\n","36:0"],[20," auwrite.py"],[20,"\n","36:0"],[20," ..."],[20,"\n","36:0"],[20," effects/ Subpackage for sound effects"],[20,"\n","36:0"],[20," echo.py"],[20,"\n","36:0"],[20," surround.py"],[20,"\n","36:0"],[20," reverse.py"],[20,"\n","36:0"],[20," ..."],[20,"\n","36:0"],[20," filters/ Subpackage for filters"],[20,"\n","36:0"],[20," equalizer.py"],[20,"\n","36:0"],[20," vocoder.py"],[20,"\n","36:0"],[20," karaoke.py"],[20,"\n","36:0"],[20," ..."],[20,"\n","36:0"],[20,"\n注:官方文档"],[20,"PEP 420 Specification","16:\"https%3A%2F%2Fwww.python.org%2Fdev%2Fpeps%2Fpep-0420%2F%23specification\""],[20," 指出,对于一些常规的包,__init__.py 仍然是需要的 ,如果将该文件删除,就会把该 Python 包变成一个本地的命名空间包,这将会产生一些额外的限制,具体可以参考这篇"],[20,"文档","16:\"https%3A%2F%2Fpackaging.python.org%2Fguides%2Fpackaging-namespace-packages%2F%23native-namespace-packages\""],[20,"。\n总结"],[20,"\n","32:1"],[20,"Python3 中的新功能远远不止如此,大家可以进一步进行探索。本文列出的内容只是一些实用的功能,希望能够对大家有所帮助。\n\n文中的代码链接:"],[20,"\n","blockquote:true"],[20,"https://github.com/Weenkus/DataWhatNow-Codes/blob/master/things_you_are_probably_not_using_in_python_3_but_should/python%203%20examples.ipynb"],[20,"\n","blockquote:true"]]" style="font-size: 15px; color: rgb(63, 63, 63); letter-spacing: 1px;">对任何一种编程语言来说,字符串处理是一项很重要的内容,字符串处理往往是很多程序的基础部分。由于人工处理字符串非常繁琐,我们更希望用一种结构化的方法来处理它们。在 Python 中,我们一般使用 format 来进行结构化字符串处理,如下所示:
bool:"],[20,"\n","36:0"],[20," return \"animal\" in sentence"],[20,"\n","36:0"],[20,"sentence_has_animal(\"Donald had a farm without animals\")"],[20,"\n","36:0"],[20,"# True"],[20,"\n","36:0"],[20,"枚举 (3.4+)"],[20,"\n","32:1"],[20," Python 3 中的 Enum 类支持"],[20,"枚举","16:\"https%3A%2F%2Fdocs.python.org%2F3%2Flibrary%2Fenum.html\""],[20,"功能,可以使我们的程序变得更加简洁。 Enum 是一种便捷的变量列表的打包方式,使用该方法能够避免多个变量在代码各处分布,使代码显得杂乱无章。\n\nfrom enum import Enum, auto"],[20,"\n\n","36:0"],[20,"class Monster(Enum):"],[20,"\n","36:0"],[20," ZOMBIE = auto()"],[20,"\n","36:0"],[20," WARRIOR = auto()"],[20,"\n","36:0"],[20," BEAR = auto()"],[20,"\n","36:0"],[20," "],[20,"\n","36:0"],[20,"print(Monster.ZOMBIE)"],[20,"\n","36:0"],[20,"# Monster.ZOMBIE"],[20,"\n","36:0"],[20,"\n枚举是一个符号集合,每个符号都和唯一的变量对应。通过使用枚举,我们可以通过符号标识来比较各个成员,我们还可以对枚举本身进行迭代。"],[20,"\n\n","blockquote:true"],[20,"https://docs.python.org/3/library/enum.html"],[20,"\n","blockquote:true"],[20,"\nfor monster in Monster:"],[20,"\n","36:0"],[20," print(monster)"],[20,"\n","36:0"],[20," "],[20,"\n","36:0"],[20,"# Monster.ZOMBIE"],[20,"\n","36:0"],[20,"# Monster.WARRIOR"],[20,"\n","36:0"],[20,"# Monster.BEAR"],[20,"\n","36:0"],[20,"\n","32:1"],[20,"内置的 LRU 缓存 (3.2+)"],[20,"\n","32:1"],[20,"在现如今使用的硬件和软件中,缓存无所不在。Python 3 通过 "],[20,"lru_cache","16:\"https%3A%2F%2Fdocs.python.org%2F3%2Flibrary%2Ffunctools.html%23functools.lru_cache\""],[20," 来使用 LRU ("],[20,"Least Recently Used","16:\"https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FCache_replacement_policies%23Least_recently_used_(LRU)\""],[20,") 缓存。\n\n下面的代码定义了一个斐波拉契函数,由于该函数的运算需要多次递归,每次递归都会执行相同的工作,因此使用缓存能够加速它的计算。\n\nimport time"],[20,"\n\n","36:0"],[20,"def fib(number: int) -> int:"],[20,"\n","36:0"],[20," if number == 0: return 0"],[20,"\n","36:0"],[20," if number == 1: return 1"],[20,"\n","36:0"],[20," "],[20,"\n","36:0"],[20," return fib(number-1) + fib(number-2)"],[20,"\n","36:0"],[20," "],[20,"\n","36:0"],[20,"start = time.time()"],[20,"\n","36:0"],[20,"fib(40)"],[20,"\n","36:0"],[20,"print(f'Duration: {time.time() - start}s')"],[20,"\n","36:0"],[20,"# Duration: 30.684099674224854s"],[20,"\n","36:0"],[20,"\n我们可以使用 lru_cache 来优化该运算。这种优化极技术称为 "],[20,"memoization","16:\"https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FMemoization\""],[20," ,它能够把执行时间从几秒缩减到几纳秒。\n\nfrom functools import lru_cache"],[20,"\n\n","36:0"],[20,"@lru_cache(maxsize=512)"],[20,"\n","36:0"],[20,"def fib_memoization(number: int) -> int:"],[20,"\n","36:0"],[20," if number == 0: return 0"],[20,"\n","36:0"],[20," if number == 1: return 1"],[20,"\n","36:0"],[20," "],[20,"\n","36:0"],[20," return fib_memoization(number-1) + fib_memoization(number-2)"],[20,"\n","36:0"],[20," "],[20,"\n","36:0"],[20,"start = time.time()"],[20,"\n","36:0"],[20,"fib_memoization(40)"],[20,"\n","36:0"],[20,"print(f'Duration: {time.time() - start}s')"],[20,"\n","36:0"],[20,"# Duration: 6.866455078125e-05s"],[20,"\n","36:0"],[20,"\n","32:1"],[20,"扩展的可迭代解析功能(3.0+)"],[20,"\n","32:1"],[20,"这里不做详细解释,直接贴出示例代码,具体解决可以参考这篇"],[20,"文档","16:\"https%3A%2F%2Fwww.python.org%2Fdev%2Fpeps%2Fpep-3132%2F\""],[20,"。\nhead, *body, tail = range(5)"],[20,"\n","36:0"],[20,"print(head, body, tail)"],[20,"\n","36:0"],[20,"# 0 [1, 2, 3] 4"],[20,"\n\n","36:0"],[20,"py, filename, *cmds = \"python3.7 script.py -n 5 -l 15\".split()"],[20,"\n","36:0"],[20,"print(py)"],[20,"\n","36:0"],[20,"print(filename)"],[20,"\n","36:0"],[20,"print(cmds)"],[20,"\n","36:0"],[20,"# python3.7"],[20,"\n","36:0"],[20,"# script.py"],[20,"\n","36:0"],[20,"# ['-n', '5', '-l', '15']"],[20,"\n\n","36:0"],[20,"first, _, third, *_ = range(10)"],[20,"\n","36:0"],[20,"print(first, third)"],[20,"\n","36:0"],[20,"# 0 2"],[20,"\n","36:0"],[20,"\n","32:1"],[20,"数据类(3.7+)"],[20,"\n","32:1"],[20,"Python 3 引入了数据类 (data class)。其装饰器会自动生成特征方法,例如 __init__() 和 __repr()__,这能够帮助减少样本代码的数量。在官方"],[20,"文档","16:\"https%3A%2F%2Fwww.python.org%2Fdev%2Fpeps%2Fpep-0557%2F\""],[20,"中,它们被称作 “具有默认值的可变命名元组” 。\n\nclass Armor:"],[20,"\n","36:0"],[20," "],[20,"\n","36:0"],[20," def __init__(self, armor: float, description: str, level: int = 1):"],[20,"\n","36:0"],[20," self.armor = armor"],[20,"\n","36:0"],[20," self.level = level"],[20,"\n","36:0"],[20," self.description = description"],[20,"\n","36:0"],[20," "],[20,"\n","36:0"],[20," def power(self) -> float:"],[20,"\n","36:0"],[20," return self.armor * self.level"],[20,"\n","36:0"],[20," "],[20,"\n","36:0"],[20,"armor = Armor(5.2, \"Common armor.\", 2)"],[20,"\n","36:0"],[20,"armor.power()"],[20,"\n","36:0"],[20,"# 10.4"],[20,"\n\n","36:0"],[20,"print(armor)"],[20,"\n","36:0"],[20,"#"],[20,"\n","36:0"],[20,"\n接来下我们使用数据类来实现上面的代码:\n\nfrom dataclasses import dataclass"],[20,"\n\n","36:0"],[20,"@dataclass"],[20,"\n","36:0"],[20,"class Armor:"],[20,"\n","36:0"],[20," armor: float"],[20,"\n","36:0"],[20," description: str"],[20,"\n","36:0"],[20," level: int = 1"],[20,"\n","36:0"],[20," "],[20,"\n","36:0"],[20," def power(self) -> float:"],[20,"\n","36:0"],[20," return self.armor * self.level"],[20,"\n","36:0"],[20," "],[20,"\n","36:0"],[20,"armor = Armor(5.2, \"Common armor.\", 2)"],[20,"\n","36:0"],[20,"armor.power()"],[20,"\n","36:0"],[20,"# 10.4"],[20,"\n\n","36:0"],[20,"print(armor)"],[20,"\n","36:0"],[20,"# Armor(armor=5.2, description='Common armor.', level=2)"],[20,"\n","36:0"],[20,"\n","32:1"],[20,"隐式命名空间包(3.3+)"],[20,"\n","32:1"],[20,"构建Python代码有很多方法,其中一种就是在包(packages)中进行构建(即包含一个 __init__.py 文件的文件夹)。以下示例由 Python 的官方文档提供:\n\nsound/ Top-level package"],[20,"\n","36:0"],[20," __init__.py Initialize the sound package"],[20,"\n","36:0"],[20," formats/ Subpackage for file format conversions"],[20,"\n","36:0"],[20," __init__.py"],[20,"\n","36:0"],[20," wavread.py"],[20,"\n","36:0"],[20," wavwrite.py"],[20,"\n","36:0"],[20," aiffread.py"],[20,"\n","36:0"],[20," aiffwrite.py"],[20,"\n","36:0"],[20," auread.py"],[20,"\n","36:0"],[20," auwrite.py"],[20,"\n","36:0"],[20," ..."],[20,"\n","36:0"],[20," effects/ Subpackage for sound effects"],[20,"\n","36:0"],[20," __init__.py"],[20,"\n","36:0"],[20," echo.py"],[20,"\n","36:0"],[20," surround.py"],[20,"\n","36:0"],[20," reverse.py"],[20,"\n","36:0"],[20," ..."],[20,"\n","36:0"],[20," filters/ Subpackage for filters"],[20,"\n","36:0"],[20," __init__.py"],[20,"\n","36:0"],[20," equalizer.py"],[20,"\n","36:0"],[20," vocoder.py"],[20,"\n","36:0"],[20," karaoke.py"],[20,"\n","36:0"],[20," ..."],[20,"\n","36:0"],[20,"\n"],[20,"在 Python 2 中,上面的每个文件夹都必须有一个 ","0:\"%23333333\""],[20," __init__.py ","31:1"],[20,"文件,该文件用于将其所在文件夹转化为 Python 包。然而在 Python 3 中,通过使用","0:\"%23333333\""],[20,"隐式命名空间包","0:\"%23333333\"|16:\"https%3A%2F%2Fwww.python.org%2Fdev%2Fpeps%2Fpep-0420%2F\""],[20,"(Implicit Namespace Package)"],[20,",这些文件就不再需要了。","0:\"%23333333\""],[20,"\n\nsound/ Top-level package"],[20,"\n","36:0"],[20," __init__.py Initialize the sound package"],[20,"\n","36:0"],[20," formats/ Subpackage for file format conversions"],[20,"\n","36:0"],[20," wavread.py"],[20,"\n","36:0"],[20," wavwrite.py"],[20,"\n","36:0"],[20," aiffread.py"],[20,"\n","36:0"],[20," aiffwrite.py"],[20,"\n","36:0"],[20," auread.py"],[20,"\n","36:0"],[20," auwrite.py"],[20,"\n","36:0"],[20," ..."],[20,"\n","36:0"],[20," effects/ Subpackage for sound effects"],[20,"\n","36:0"],[20," echo.py"],[20,"\n","36:0"],[20," surround.py"],[20,"\n","36:0"],[20," reverse.py"],[20,"\n","36:0"],[20," ..."],[20,"\n","36:0"],[20," filters/ Subpackage for filters"],[20,"\n","36:0"],[20," equalizer.py"],[20,"\n","36:0"],[20," vocoder.py"],[20,"\n","36:0"],[20," karaoke.py"],[20,"\n","36:0"],[20," ..."],[20,"\n","36:0"],[20,"\n注:官方文档"],[20,"PEP 420 Specification","16:\"https%3A%2F%2Fwww.python.org%2Fdev%2Fpeps%2Fpep-0420%2F%23specification\""],[20," 指出,对于一些常规的包,__init__.py 仍然是需要的 ,如果将该文件删除,就会把该 Python 包变成一个本地的命名空间包,这将会产生一些额外的限制,具体可以参考这篇"],[20,"文档","16:\"https%3A%2F%2Fpackaging.python.org%2Fguides%2Fpackaging-namespace-packages%2F%23native-namespace-packages\""],[20,"。\n总结"],[20,"\n","32:1"],[20,"Python3 中的新功能远远不止如此,大家可以进一步进行探索。本文列出的内容只是一些实用的功能,希望能够对大家有所帮助。\n\n文中的代码链接:"],[20,"\n","blockquote:true"],[20,"https://github.com/Weenkus/DataWhatNow-Codes/blob/master/things_you_are_probably_not_using_in_python_3_but_should/python%203%20examples.ipynb"],[20,"\n","blockquote:true"]]" style="font-size: 15px; color: rgb(63, 63, 63); letter-spacing: 1px;">
- [/code][code]log_message = 'User {} has logged in and did an action {}.'.format(
复制代码- [/code][code]print(log_message)
复制代码- # User Jane Doe has logged in and did an action bu
复制代码
除了 format 之外, Python 3 还提供了一个更加灵活的方法来处理字符串,那就是 f-string 。如下所示,我们用 f-string 来和实现上面代码相同的功能:
- [/code][code]log_message = f'User {user} has logged in and did an action {action}.'
复制代码- # User Jane Doe has logged in and did an action buy.
复制代码
Pathlib (3.4+)
如果需要处理文件路径,我们可以使用 Python 3 中的 pathlib 库,使对文件路径的操作更加便捷。如果你对 pathlib 存在疑惑,可以参考这篇文章。下面提供了一个代码示例:
- [/code][code]root = Path('post_sub_folder')
复制代码- [/code][code]path = root / 'happy_user'
复制代码- # /home/weenkus/Workspace/Projects/DataWhatNow-Codes/how_your_python3_should_look_like/post_sub_folder/happy_user
复制代码
类型提示 (3.5+)
静态类型与动态类型是软件工程中的一个热门话题,Python 3 提供了支持 type hinting(类型提示)的方法,下面提供了一个示例:
- def sentence_has_animal(sentence: str) -> bool:
复制代码- return "animal" in sentence
复制代码- sentence_has_animal("Donald had a farm without animals")
复制代码
枚举 (3.4+)
Python 3 中的 Enum 类支持枚举功能,可以使我们的程序变得更加简洁。 Enum 是一种便捷的变量列表的打包方式,使用该方法能够避免多个变量在代码各处分布,使代码显得杂乱无章。
- from enum import Enum, auto
复制代码- [/code][code]class Monster(Enum):
复制代码 枚举是一个符号集合,每个符号都和唯一的变量对应。通过使用枚举,我们可以通过符号标识来比较各个成员,我们还可以对枚举本身进行迭代。
https://docs.python.org/3/library/enum.html
内置的 LRU 缓存 (3.2+)
在现如今使用的硬件和软件中,缓存无所不在。Python 3 通过 lru_cache 来使用 LRU (Least Recently Used) 缓存。
下面的代码定义了一个斐波拉契函数,由于该函数的运算需要多次递归,每次递归都会执行相同的工作,因此使用缓存能够加速它的计算。
- [/code][code]def fib(number: int) -> int:
复制代码- return fib(number-1) + fib(number-2)
复制代码- print(f'Duration: {time.time() - start}s')
复制代码- # Duration: 30.684099674224854s
复制代码
我们可以使用 lru_cache 来优化该运算。这种优化极技术称为 memoization ,它能够把执行时间从几秒缩减到几纳秒。
- from functools import lru_cache
复制代码- [/code][code]@lru_cache(maxsize=512)
复制代码- def fib_memoization(number: int) -> int:
复制代码- return fib_memoization(number-1) + fib_memoization(number-2)
复制代码- print(f'Duration: {time.time() - start}s')
复制代码- [/code][code]# Duration: 6.866455078125e-05s
复制代码
扩展的可迭代解析功能(3.0+)
这里不做详细解释,直接贴出示例代码,具体解决可以参考这篇文档。
- head, *body, tail = range(5)
复制代码- py, filename, *cmds = "python3.7 script.py -n 5 -l 15".split()
复制代码- # ['-n', '5', '-l', '15']
复制代码- first, _, third, *_ = range(10)
复制代码
数据类(3.7+)
Python 3 引入了数据类 (data class)。其装饰器会自动生成特征方法,例如 __init__() 和 __repr()__,这能够帮助减少样本代码的数量。在官方文档中,它们被称作 “具有默认值的可变命名元组” 。
- def __init__(self, armor: float, description: str, level: int = 1):
复制代码- self.description = description
复制代码- def power(self) -> float:
复制代码- return self.armor * self.level
复制代码- armor = Armor(5.2, "Common armor.", 2)
复制代码- [/code][code]print(armor)
复制代码
接来下我们使用数据类来实现上面的代码:
- from dataclasses import dataclass
复制代码- def power(self) -> float:
复制代码- return self.armor * self.level
复制代码- armor = Armor(5.2, "Common armor.", 2)
复制代码- [/code][code]print(armor)
复制代码- # Armor(armor=5.2, description='Common armor.', level=2
复制代码
隐式命名空间包(3.3+)
构建Python代码有很多方法,其中一种就是在包(packages)中进行构建(即包含一个 __init__.py 文件的文件夹)。以下示例由 Python 的官方文档提供:
- __init__.py Initialize the sound package
复制代码- formats/ Subpackage for file format conversions
复制代码- effects/ Subpackage for sound effects
复制代码- filters/ Subpackage for filters
复制代码
在 Python 2 中,上面的每个文件夹都必须有一个 __init__.py 文件,该文件用于将其所在文件夹转化为 Python 包。然而在 Python 3 中,通过使用隐式命名空间包(Implicit Namespace Package:https://www.python.org/dev/peps/pep-0420/),这些文件就不再需要了。
- __init__.py Initialize the sound package
复制代码- formats/ Subpackage for file format conversions
复制代码- effects/ Subpackage for sound effects
复制代码- filters/ Subpackage for filters
复制代码
注:官方文档PEP 420 Specification 指出,对于一些常规的包,__init__.py 仍然是需要的 ,如果将该文件删除,就会把该 Python 包变成一个本地的命名空间包,这将会产生一些额外的限制,具体可以参考这篇文档。
总结
Python3 中的新功能远远不止如此,大家可以进一步进行探索。本文列出的内容只是一些实用的功能,希望能够对大家有所帮助。文中的代码链接:
https://github.com/Weenkus/DataWhatNow-Codes/blob/master/things_you_are_probably_not_using_in_python_3_but_should/python%203%20examples.ipynb
原文链接:
https://datawhatnow.com/things-you-are-probably-not-using-in-python-3-but-should/ (*本文由Python大本营编译,转载请联系微信1092722531)
◆
CTA核心技术及应用峰会
◆
5月25-27日,由中国IT社区CSDN与数字经济人才发展中心联合主办的第一届CTA核心技术及应用峰会将在杭州国际博览中心隆重召开,峰会将围绕人工智能领域,邀请技术领航者,与开发者共同探讨机器学习和知识图谱的前沿研究及应用。
更多重磅嘉宾请识别海报二维码查看。目前会议8折预售票抢购中,点击阅读原文即刻抢购。添加小助手微信15101014297,备注“CTA”,了解票务以及会务详情。
点击阅读原文,了解「CTA核心技术及应用峰会」
|
|