雁过留声

a tiger in me sniffs roses

0%

python3 新特性总结

1. f-string 字符串插值

传统字符串格式化是使用%, python2.6 后引入了format提供了更强大,灵活的控制。python3 开始提供了字符串插值的方法,更加方便,清晰。这种方式在其它语言中并不陌生。

1
2
3
4
5
a = "Peeter"
b = 50
s = "{0} has {1:.2f} kg".format(a, b)

s2 = f"{a} has {b:.2f} kg"

2. 类型提示(python3.5)

在代码提示和可读性上很有帮助
a. 变量定义

1
2
3
x:int = 10
y:str = 'hello'
c:list = []

b. 函数定义

1
2
3
4
5
def add(x:int,y:int)->int:
return x+y

print(add(10,12))
print(add('hello','world')) # ”编译“不会出错

类型提示并不能在运行时做类型检查

3. 枚举提供了另一种定义常量的方法(python 3.4)

Enum模块定义了四个枚举类,它们可被用来定义名称和值的不重复集合: Enum, IntEnum, Flag 和 IntFlag。 此外还定义了一个装饰器 unique() 和一个辅助类 auto

1
2
3
4
5
6
7
8
9
from enum import Enum, auto
class Color(Enum):
RED = auto()
GREEN = auto()
BLUE = auto()
print(Color.Red) #Color.RED
print(repr(Color.RED)) # <Color.RED: 1>
for c in Color:
print(c)

4. Data class 装饰器 (python 3.7+)

减少样板代码,熟悉java spring的一定对@Data注解不默生。装饰器会自动生成诸如__init__和__repr__这样的特殊方法

1
2
3
4
5
6
7
8
9
10
11
12
13
from dataclass import dataclass
@dataclass
class Square:
w: float
h: float
desc: str

def area(self)->float:
return w*h

s = Square(5.2, 2, 'a square')
print(s)
print(s.area())

5. 扩展的可迭代对象解包

es6 中有解构这个特性,算是一个不完整的版本。使用*x表示余下的迭代对象

1
2
3
4
5
6
7
8
9
10
head, *body, tail = range(5)
print(head, body, tail)
# 0 [1, 2, 3] 4

first, _, third, *_ = range(5)
print(first, third)

seq = range(5)
first, rest = seq[0], seq[1:]
first, *rest = seq

6. LRU 缓存 (python3.2)

使用functools模块的lur_cache装饰器,可以缓存最多 maxsize 个此函数的调用结果,从而提高程序执行的效率,特别适合于耗时的函数。参数maxsize为最多缓存的次数,如果为None,则无限制。如果 typed=True,则不同参数类型的调用将分别缓存,例如 f(3) 和 f(3.0)。
被 lru_cache 装饰的函数会有 cache_clear 和 cache_info 两个方法,分别用于清除缓存和查看缓存信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from functools import lru_cache

@lru_cache(maxsize=6)
def add(x, y):
print(f"calc {x} + {y}")
return x + y

print(add(1, 2))
print(add(1, 2)) # 第二次调用直接返回
print(add(2, 3))

print(add.cache_info())
#CacheInfo(hits=1, misses=2, maxsize=6, currsize=1)
add.cache_clear()
print(type(add)) # <class 'functools._lru_cache_wrapper'>

7. pathlib (python3.4)

可以更好操作路径了

1
2
3
4
import os.path

BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
TEMPLATES_DIR = os.path.join(BASE_DIR, 'templates')

vs

1
2
3
4
from pathlib import Path

BASE_DIR = Path(__file__).resolve().parent.parent
TEMPLATES_DIR = BASE_DIR.joinpath('templates')
1
2
3
4
5
import os
import os.path

os.makedirs(os.path.join('src', '__pypackages__'), exist_ok=True)
os.rename('.editorconfig', os.path.join('src', '.editorconfig'))

vs

1
2
3
4
5
from pathlib import Path

Path('src/__pypackages__').mkdir(parents=True, exist_ok=True)
Path('.editorconfig').rename('src/.editorconfig')
# 不必关心是/ 还是\