几个你所应该知晓的python3特性[python3.7及前版本]
Page content
时至今日,python2
大限已到,且python3
对各类原有框架及模块都有了非常好的支持。下面给大家简单介绍一些或许你不常用的,但你应该知道的那些 新特性。
模板语法 f-strings
首先我们或许比较习惯使用.format()
nums = 4
name = 'tasks'
time = 5.6
'{} {} done, used {}s'.format(nums,name,time)
4 tasks done , cost 5.6s
接下来我们使用'f'
模板语法, 有没有发现可读性提高了不少!
f'{nums+1} {name} done, used {time}s'
5 tasks done , cost 5.6s
解包扩展
以前我们更新一个字典或许需要这样
dict_a = {'a':'b'}
dict_b = {'c':'d'}
dict_a.update(dict_b)
# output
{'a': 'b', 'c': 'd'} # dict_a
而在python3
中我们可以这样, *
操作tuple
、list
等同理
{**dict_a,**dict_b}
# output
{'a': 'b', 'c': 'd'}
输入预提示
为了增强函数及返回值的类型提示,我们可以这样来定义一个poc
函数, 提示urls
变量是成员为str
的元祖、payload
为PAYLOAD
类, 而超时时间为float
类型, 默认值5秒,最终返回结果将为一个布尔值。
from typing import Tuple
class PAYLOAD:
...
def poc(urls: Tuple[str], payload: PAYLOAD, timeout: float = 5) -> bool:
...
return is_vul
async 与await 关键字及asycio
这里通过一个协程并发的案例来作简单说明。这里设定两个任务。
- 任务1: 执行睡眠2秒
- 任务2: 执行睡眠1秒
import asyncio
import logging
logging.basicConfig(level=logging.DEBUG, format="[%(asctime)s]%(message)s")
log = logging.getLogger()
async def sleep(task, times: int):
log.info(f"task {task} start.")
await asyncio.sleep(times)
log.info(f"task {task} done.")
async def main():
await asyncio.gather(
sleep(1, 2),
sleep(2, 1)
)
asyncio.run(main())
# output
[07:30:09,109]Using selector: KqueueSelector
[07:30:09,110]task 1 start.
[07:30:09,111]task 2 start.
[07:30:10,113]task 2 done.
[07:30:11,115]task 1 done.
从输出结果我们可以看到,整个过程只花费了两秒钟。
路径遍历增强
现在我们使用os.scandir()
来代替原有的os.walk()
, 且其的执行效率将提高3至5倍。
for entry in os.scandir(path): # 扫描path路径
if not entry.name.startswith('.') and entry.is_file(): # 过滤掉文件夹
print(entry.name) # 打印出文件名
枚举Enum
假设我们设定一组星期数据。
Sun = 1
Mon = 2
...
Sat = 7
并用来判定一周的第N天是周几的时候,我们可以这么写
days = int(N)
if(N==Mon){
print('Mon')
}
else if(N==Tue){
print('Tue')
}
...
else{
print('Sun')
}
但是我们有没有发现这样写有点 麻烦呢, 于是我们将它改为enum
对象, 是否有变得简单很多呢~
from enum import Enum, unique
@unique
class week(Enum):
Sun = 1
Mon = 2
...
Sat = 7
week(1).name # Sun
print(week(7)) # week.Sat
week.Sun.value == 1 # True
lru_cache
这是一个可以为函数提供缓存功能的装饰器,在下次以相同参数调用时直接返回上一次的结果。用以节约高开销或I/O函数的调用时间。
例如我们可以用以高效计算斐波那契数列。
from functools import lru_cache
@lru_cache(maxsize=None)
def fib(n):
if n < 2:
return n
return fib(n-1) + fib(n-2)
[fib(n) for n in range(32)]
# 常规操作
# python3 test.py 1.85s user 0.03s system 98% cpu 1.915 total
# lru_cache
# python3 test.py 0.04s user 0.02s system 90% cpu 0.066 total
在未加上@lru_cache(maxsize=None)
时使用了 1.91秒, 而在加上之后只花费了 0.06秒。
数据类 Data classes
以前我们要定义一个类或许需要这样
class food:
def __init__(self, name: str, overdue: bool = False) -> None:
self.name = name
self.overdue = overdue
class animal:
def __init__(self, name: str, age: int = 1) -> food:
self.name = name
self.age = age
def eat(self, thing: food) -> bool:
if not thing.overdue:
return True
meat = food('meat')
dog = animal("dog", 1)
dog.eat(meat)
而现在我们可以这样, 它将帮你自动完成__init__
,__repr__
,__eq__
等方法。
from dataclasses import dataclass
@dataclass
class food:
name: str
overdue: bool = False
@dataclass
class animal:
name: str
age: int = 1
def eat(self, thing: food) -> bool:
if not thing.overdue:
return True
meat = food('meat',True)
dog = animal("dog", 1)
dog.eat(meat)
# output
False