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

640?wx_fmt=jpeg


作者 | 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_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")	
	
# 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.684099674224854s


我们可以使用 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)


CTA核心技术及应用峰会


5月25-27日,由中国IT社区CSDN与数字经济人才发展中心联合主办的第一届CTA核心技术及应用峰会将在杭州国际博览中心隆重召开,峰会将围绕人工智能领域,邀请技术领航者,与开发者共同探讨机器学习和知识图谱的前沿研究及应用。


更多重磅嘉宾请识别海报二维码查看点击阅读原文即刻抢购。添加小助手微信15101014297,备注“CTA”,了解票务以及会务详情。


640?wx_fmt=jpeg


推荐阅读


640?wx_fmt=png

点击阅读原文,了解CTA核心技术及应用峰会

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值