@程序员,Python 3 还有哪些未 Get 的潜藏技能?| 技术头条


作者 | Vinko Kod?oman
翻译 | 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 版本。
f-strings?(3.6+)
对任何一种编程语言来说,字符串处理是一项很重要的内容,字符串处理往往是很多程序的基础部分。由于人工处理字符串非常繁琐,我们更希望用一种结构化的方法来处理它们。在 Python 中,我们一般使用 format 来进行结构化字符串处理,如下所示:
user?=?"Jane?Doe"
action?=?"buy"
log_message?=?'User?{}?has?logged?in?and?did?an?action?{}.'.format(
??user,
??action
)
print(log_message)
#?User?Jane?Doe?has?logged?in?and?did?an?action?bu
除了 format 之外, Python 3 还提供了一个更加灵活的方法来处理字符串,那就是 f-string 。如下所示,我们用 f-string 来和实现上面代码相同的功能:
user?=?"Jane?Doe"
action?=?"buy"
log_message?=?f'User?{user}?has?logged?in?and?did?an?action?{action}.'
print(log_message)
#?User?Jane?Doe?has?logged?in?and?did?an?action?buy
Pathlib (3.4+)
如果需要处理文件路径,我们可以使用 Python 3 中的 pathlib 库,使对文件路径的操作更加便捷。如果你对 pathlib 存在疑惑,可以参考这篇文章。下面提供了一个代码示例:
from?pathlib?import?Path
root?=?Path('post_sub_folder')
print(root)
#?post_sub_folder
path?=?root?/?'happy_user'
#?Make?the?path?absolute
print(path.resolve())
#?/home/weenkus/Workspace/Projects/DataWhatNow-Codes/how_your_python3_should_look_like/post_sub_folder/happy_use
类型提示 (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")
#?True
枚举 (3.4+)
Python 3 中的 Enum 类支持枚举功能,可以使我们的程序变得更加简洁。 Enum 是一种便捷的变量列表的打包方式,使用该方法能够避免多个变量在代码各处分布,使代码显得杂乱无章。
from?enum?import?Enum,?auto
class?Monster(Enum):
????ZOMBIE?=?auto()
????WARRIOR?=?auto()
????BEAR?=?auto()
print(Monster.ZOMBIE)
#?Monster.ZOMBIE
枚举是一个符号集合,每个符号都和唯一的变量对应。通过使用枚举,我们可以通过符号标识来比较各个成员,我们还可以对枚举本身进行迭代。
https://docs.python.org/3/library/enum.html
for?monster?in?Monster:
????print(monster)
#?Monster.ZOMBIE
#?Monster.WARRIOR
#?Monster.BEAR
内置的 LRU 缓存 (3.2+)
在现如今使用的硬件和软件中,缓存无所不在。Python 3 通过 lru_cache 来使用 LRU (Least Recently Used) 缓存。
下面的代码定义了一个斐波拉契函数,由于该函数的运算需要多次递归,每次递归都会执行相同的工作,因此使用缓存能够加速它的计算。
import?time
def?fib(number:?int)?->?int:
????if?number?==?0:?return?0
????if?number?==?1:?return?1
????return?fib(number-1)?+?fib(number-2)
start?=?time.time()
fib(40)
print(f'Duration:?{time.time()?-?start}s')
#?Duration:?30.684099674224854
我们可以使用 lru_cache 来优化该运算。这种优化极技术称为 memoization ,它能够把执行时间从几秒缩减到几纳秒。
from?functools?import?lru_cache
@lru_cache(maxsize=512)
def?fib_memoization(number:?int)?->?int:
????if?number?==?0:?return?0
????if?number?==?1:?return?1
????return?fib_memoization(number-1)?+?fib_memoization(number-2)
start?=?time.time()
fib_memoization(40)
print(f'Duration:?{time.time()?-?start}s')
#?Duration:?6.866455078125e-05s
扩展的可迭代解析功能(3.0+)
这里不做详细解释,直接贴出示例代码,具体解决可以参考这篇文档。
head,?*body,?tail?=?range(5)
print(head,?body,?tail)
#?0?[1,?2,?3]?4
py,?filename,?*cmds?=?"python3.7?script.py?-n?5?-l?15".split()
print(py)
print(filename)
print(cmds)
#?python3.7
#?script.py
#?['-n',?'5',?'-l',?'15']
first,?_,?third,?*_?=?range(10)
print(first,?third)
#?0?
数据类(3.7+)
Python 3 引入了数据类 (data class)。其装饰器会自动生成特征方法,例如 __init__() 和 __repr()__,这能够帮助减少样本代码的数量。在官方文档中,它们被称作 “具有默认值的可变命名元组” 。
class?Armor:
????def?__init__(self,?armor:?float,?description:?str,?level:?int?=?1):
????????self.armor?=?armor
????????self.level?=?level
????????self.description?=?description
????def?power(self)?->?float:
????????return?self.armor?*?self.level
armor?=?Armor(5.2,?"Common?armor.",?2)
armor.power()
#?10.4
print(armor)
#?<__main__ .Armor?object?at?0x7fc4800e2cf8
接来下我们使用数据类来实现上面的代码:
from?dataclasses?import?dataclass
@dataclass
class?Armor:
????armor:?float
????description:?str
????level:?int?=?1
????def?power(self)?->?float:
????????return?self.armor?*?self.level
armor?=?Armor(5.2,?"Common?armor.",?2)
armor.power()
#?10.4
print(armor)
#?Armor(armor=5.2,?description='Common?armor.',?level=2
隐式命名空间包(3.3+)
构建Python代码有很多方法,其中一种就是在包(packages)中进行构建(即包含一个 __init__.py 文件的文件夹)。以下示例由 Python 的官方文档提供:
sound/??????????????????????????Top-level?package
??????__init__.py???????????????Initialize?the?sound?package
??????formats/??????????????????Subpackage?for?file?format?conversions
??????????????__init__.py
??????????????wavread.py
??????????????wavwrite.py
??????????????aiffread.py
??????????????aiffwrite.py
??????????????auread.py
??????????????auwrite.py
??????????????...
??????effects/??????????????????Subpackage?for?sound?effects
??????????????__init__.py
??????????????echo.py
??????????????surround.py
??????????????reverse.py
??????????????...
??????filters/??????????????????Subpackage?for?filters
??????????????__init__.py
??????????????equalizer.py
??????????????vocoder.py
??????????????karaoke.py
??????????????...
在 Python 2 中,上面的每个文件夹都必须有一个 ?__init__.py 文件,该文件用于将其所在文件夹转化为 Python 包。然而在 Python 3 中,通过使用隐式命名空间包(Implicit Namespace Package:https://www.python.org/dev/peps/pep-0420/),这些文件就不再需要了。
sound/??????????????????????????Top-level?package
??????__init__.py???????????????Initialize?the?sound?package
??????formats/??????????????????Subpackage?for?file?format?conversions
??????????????wavread.py
??????????????wavwrite.py
??????????????aiffread.py
??????????????aiffwrite.py
??????????????auread.py
??????????????auwrite.py
??????????????...
??????effects/??????????????????Subpackage?for?sound?effects
??????????????echo.py
??????????????surround.py
??????????????reverse.py
??????????????...
??????filters/??????????????????Subpackage?for?filters
??????????????equalizer.py
??????????????vocoder.py
??????????????karaoke.py
??????????????...
注:官方文档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)
【End】

作为码一代,想教码二代却无从下手:
听说少儿编程很火,可它有哪些好处呢?
孩子多大开始学习比较好呢?又该如何学习呢?
最新的编程教育政策又有哪些呢?
下面给大家介绍CSDN新成员:极客宝宝(ID:geek_baby)
戳他了解更多↓↓↓

?热 文?推 荐?
?华为自研操作系统最快秋季面市;马化腾谈华为事件;微信支付回应遭封禁 | 极客头条
?GitHub 开源跨平台神器 Electron 实践 | 技术头条
?揭秘清华 AI 学堂班:姚期智担任首席教授,2019 年首批招收 30 人
?Google Android 向华为“闭源”!华为手机迎来至暗时刻!
?"两年前我对区块链的了解为零, 两年后我成了工程师" 我是如何得到第一份工作的?
?ICML 2019接受论文:清华、北大领跑,谷歌强压枝头,BAT略显“低调”
点击阅读原文,输入关键词,即可搜索您想要的 CSDN 文章。

关注公众号:拾黑(shiheibook)了解更多
[广告]赞助链接:
四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/
关注网络尖刀微信公众号随时掌握互联网精彩
- 1 习近平将发表二〇二六年新年贺词 7904141
- 2 2026年国补政策来了 7808738
- 3 东部战区:开火!开火!全部命中! 7712893
- 4 2026年这些民生政策将惠及百姓 7616985
- 5 小学食堂米线过期2.5小时被罚5万 7519709
- 6 解放军喊话驱离台军 原声曝光 7428214
- 7 为博流量直播踩烈士陵墓?绝不姑息 7327605
- 8 每月最高800元!多地发放养老消费券 7238391
- 9 数字人民币升级 1月1日起将计付利息 7141831
- 10 2026年1月1日起 一批新规将施行 7040675


CSDN
