根据Python EOL政策,Python 2的还剩下7个月的维护时间,此后从2020年开始Python即将停止维护更新。大家肯定已经开始逐渐用起了Python 3了,但是Python 3的新功能、新语法可能很多人还都没用起来。本文虫虫建给大家实例介绍一些Python 3非常好用的功能h语法,本文中所有的示例基于Jupyter Notebook+Python 3.7编写的。
f-strings
在编程语言中字符处理是最基本的功能,在Python我们习惯的字符处理格式是下面这样的format的方式:
user = "Chongchong"
action = "print"
log_message = '用户{} 登陆,并且操作 {} !'.format(
user,
action
)
print(log_message)
结果:
除了format之外,Python 3还引入了一种通过f-string更灵活的字符串插值的方法。使用f-strings的上述代码如下所示:
user = "Chongchong"
action = "print"
log_message = f'用户 登陆,并且操作了 。'
print(log_message)
结果:
是不是很简单方便,有了点Perl字符的意味?
Pathlib
为了方便处理文件路径等路径类的字符串, Python 3提供了pathlib来处理文件路径,他的使用也非常简单:
from pathlib import Path
root = Path('Newdir')
print(root)
path = root / 'Chongchong'
print(path.resolve())
代码解析:其中Path操作新引入一个目录,resolve()函数解析出绝对路径,结果如下:
类型提示
变量类型是动态语言和静态语言根本区分之一,静态类型安全高效,是使用比较繁琐。动态类型使用灵活方便,但是性能安全性较差,容易出现变量类型的混淆不太确定。Python 3中推出了一个类型提示功能,可以让我们验证的变量类型是是不是正常。
def sayhello(name: str) -> str:
return 'Hello ' + name
# sayhello ("虫虫") # Hello虫虫
sayhello (55)
结果会报错,类型不匹配:
枚举
Python 3支持通过Enum类方便的生成枚举类型。枚举是一种存储常量列表的便捷的数据结构,使用枚举非常我们方便地统一管理常量和保持代码整洁。
from enum import Enum, auto
class SPORTS(Enum):
RACE = auto()
SWIMMING = auto()
BALL = auto()
SKIIING = auto()
SPORTS(2)
结果如下:
数据类
在Python 3中开始引入了数据类的功能。数据类没有语法限制,可用于减少样板代码,装饰器会自动生成特殊方法,例如__init__()以及__repr()__。从官方proposal中叫做"具有默认值的可变命名元组"。举个简单的例子:
class Sum:
def __init__(self, digi: float, description: str, level: int = 1):
self.digi = digi
self.level = level
self.description = description
def power(self) -> float:
return pow(self.digi,self.level)
dig = Sum(5.2, "计算类", 2)
print(dig.power())
print(dig.description)
print(dig)
结果:
我们使用数据类来实现相同的功能:
from dataclasses import dataclass
@dataclass
class Sumd:
digi: float
description: str
level: int = 1
def power(self) -> float:
return pow(self.digi ,self.level)
digd= Sumd(5.2, "数据类", 2)
print(digd.power())
print(digd)
结果如下:
lru_cache缓存
高速缓存是有效提高系统性能的最有效的方式。Python 3提供一个装饰器lru_cache用来表示LRU(最近最少使用)缓存,通过该装饰器我们可以非常翻遍的使用缓存。我们以近点的递归算法示例Fibonacci数组的计算来展示缓存的巨大作用。
首先是没有缓存的版本:
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(36)
结果:
耗时:8s多
我们使用用lru_cache优化它代码:
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(100)
print(f'Duration: s')
结果:
我可以试着改变参数,不论计算多大的数字,结果都会在纳秒级别出来,而对第一个没有缓存的版本,如果n再大的话就太耗时算不出来了。
可扩展递归解包
看代码:
head, *body, tail = range(5)
print(head, body, tail)
py, filename, *cmds = "python3.7 script.py -n 5 -l 15".split()
print(py)
print(filename)
print(cmds)
first, _, third, *_ = range(10)
print(first, third)
结果很能说明功能,该功能非常适用于赋值,命令行参数解析等。
隐式命名空间包
Python代码类库常见的组织方法是用包packages(带有__init__.py文件的文件夹)。下面一个示例是Python文档:
在Python 2中,每个文件夹都必须有一个__init__.py文件,该文件实现将当前目录转换为Python包。在Python 3中,引入了隐式命名空间包,__init__.py将成为历史。
总结
本文中虫虫给大家介绍了一些个人认为值得掌握的Python 3功能,更多的功能请参考Python官方文档,如果你有比较喜欢的Python 3好用的新功能,也请你回复介绍给大家。
领取专属 10元无门槛券
私享最新 技术干货