python
from typing import Dict, Optional, Tuple
作用
为变量、函数参数、返回值提供类型提示,不改变运行时行为,但便于静态检查(如 mypy)、IDE 自动补全和代码理解。
各类型含义
Dict:字典类型注解
例如 Dict[str, int] 表示键为字符串、值为整数的字典。
示例:
python
rom typing import Dict
# 声明一个变量: 键为字符串,值为整数
user_scores : Dict[str, int] = {"XPS": 90, "XAD": 87}
# 函数参数和返回值: 接受字典, 返回字典
def filter_scores(scores: Dict[str, int], min_score: int) -> Dict[str, int]:
return {name: score for name, score in scores.items() if score > min_score}
filtered = filter_scores(user_scores, 88)
print(filtered)
运行结果:
python
{'XPS': 90}
Optional:表示值可以是某种类型或 None
例如 Optional[str] 等价于 Union[str, None]。
示例:
python
from typing import Optional
def greet(name: Optional[str] = None) -> str:
if name is None:
return "Hello, guest!"
return f"Hello, {name}!"
print(greet())
print(greet("LiLei"))
运行结果:
python
Hello, guest!
Hello, LiLei!
Tuple:元组类型注解(固定长度)
例如 Tuple[float, float] 表示包含两个浮点数的元组。
示例:
python
from typing import Tuple
# 返回一个包含两个浮点数的元组
def get_cofficients(element: str) -> Tuple[float, float]:
if element == "Fe":
return 0.25, 10.5
elif element == "Gu":
return 0.55, 9.5
else:
return 0.1, 8.7
a,b = get_cofficients("Gu")
print(f"Gu: a={a}, b={b}")
a,b =get_cofficients("Fe")
print(f"Fe: a={a}, b={b}")
运行结果:
python
Gu: a=0.55, b=9.5
Fe: a=0.25, b=10.5
三者结合:缓存字典
python
from __future__ import annotations
from typing import Dict, Tuple, Optional
coeff_cache: Dict[str, Tuple[float, float]] = {}
def get_coefficient_with_cache(element: str) -> Optional[Tuple[float, float]]:
return coeff_cache.get(element)
coeff_cache["Fe"] = (0.25,10.5)
result = get_coefficient_with_cache("Fe")
if result is not None:
a,b = result
print(f"Found Fe: a={a}, b={b}")
else:
print("Fe Not in cache")
result = get_coefficient_with_cache("Fe")
result = get_coefficient_with_cache("Xe")
if result is not None:
a,b = result
print(f"Found Xe: a={a}, b={b}")
else:
print("Xe Not in cache")
运行结果:
python
Found Fe: a=0.25, b=10.5
Not in cache Xe
pathlib.Path
python
from pathlib import Path
作用:提供面向对象的文件系统路径操作,比 os.path 更直观、跨平台。
常用方法:
- Path(file).resolve():获取当前脚本的绝对路径。
- .parents[1]:获取祖父目录。
- / 运算符:拼接路径,如 Path('/a') / 'b' / 'file.txt'。
使用示例:
python
from pathlib import Path
print(f"current file path: {Path(__file__).resolve()}")
print(f"pparent path:{Path(__file__).resolve().parents[1]}")
运行结果:
python
current file path: /home/blctrl/py/2.py
pparent path:/home/blctrl
dataclasses
dataclasses 模块是 Python 3.7 引入的标准库,用于简化类的定义,特别是那些主要用来存储数据的类。dataclass 装饰器和 field 函数是该模块的核心。
1. @dataclass 装饰器
作用:自动为类添加常用的特殊方法,如 init、repr、eq、hash 等,从而减少样板代码。如果不使用 @dataclass,手动实现同样的类需要写很多 init 和 repr 代码。
基本示例
python
from dataclasses import dataclass
@dataclass
class Student:
name: str
age: int
email: str = "" # 默认值
stu = Student("Xiaoming", 12, "xiaoming@ustc.edu.cn")
print(stu)
print(stu.name)
运行结果:
python
Student(name='Xiaoming', age=12, email='xiaoming@ustc.edu.cn')
Xiaoming
2. field 函数
作用:为字段提供更精细的控制,例如:
- 设置默认值(default)
- 设置默认工厂函数(default_factory,用于可变默认值如列表、字典)
- 控制是否出现在 repr 中(repr=True/False)
- 控制是否参与比较(compare=True/False)
- 控制是否作为 init 参数(init=True/False)
常用参数
|-----------------|------------------------------|
| 参数 | 说明 |
| default | 字段的默认值 |
| default_factory | 提供默认值的可调用对象(无参数),用于可变类型 |
| init | 是否作为 init 的参数(默认 True) |
| repr | 是否包含在 repr 字符串中(默认 True) |
| compare | 是否参与比较(<、== 等,默认 True) |
| hash | 是否计算哈希值(默认与 compare 相同) |
| metadata | 附加信息字典,不影响 dataclass 行为 |
示例
1 默认值和默认工厂
python
from dataclasses import dataclass, field
from typing import List
@dataclass
class Student:
name: str
grades: List[int] = field(default_factory=list)
age: int = 18
stu1 = Student("Xiaoming")
stu1.grades.append(85)
print(stu1)
stu2 = Student("Zhangsan")
print(stu2)
运行结果:
python
Student(name='Xiaoming', grades=[85], age=18)
Student(name='Zhangsan', grades=[], age=18)
如果不使用 default_factory 而写 grades: List[int] = [],所有实例会共享同一个列表,导致意外行为。
2 排除字段
python
@dataclass
class User:
username: str
password: str = field(repr=False)
is_admin: bool = False
user = User("admin","secret", True)
print(user)
运行结果:
python
User(username='admin', is_admin=True) # 密码被隐藏
3 只读字段(不在 init 中)
python
@dataclass
class Product:
name: str
price: float
tax : float = field(init=False, default=0.2) # 不在构造函数中传入
prod = Product("Computer",2000)
print(prod)
运行结果:
python
Product(name='Computer', price=2000, tax=0.2)
4. 后初始化(__post_init__)
python
@dataclass
class Rectangle:
width: float
height: float
area: float = field(init=False)
def __post_init__(self):
self.area = self.width * self.height
rect = Rectangle(3,4)
print(rect.area) # 运行结果12
5.冻结实例(不可变)
python
@dataclass(frozen=True)
class Point:
x: int
y: int
pt = Point(3,4)
print(pt)
pt.x = 5
运行结果:
python
Point(x=3, y=4)
Traceback (most recent call last):
File "/home/blctrl/py/4.py", line 54, in <module>
pt.x = 5
^^^^
File "<string>", line 4, in __setattr__
dataclasses.FrozenInstanceError: cannot assign to field 'x'
dataclass 会按照字段声明的顺序生成 init 参数。子类会先列出基类的字段,再列出自己的字段。
使用 dataclass
- 类主要用于存储数据,很少包含复杂方法。
- 需要自动生成 init、repr、eq 等。
- 希望减少样板代码,提高可读性。
- 对于非常简单的数据结构(如两个值的元组),namedtuple 也是一种选择,但 dataclass 更灵活(可变、默认值、类型提示)。
总结
- @dataclass 自动生成 init、repr 等常见方法。
- field() 用于精细控制每个字段的行为(默认值、是否显示、是否参与比较等)。
- 使用 dataclass 可以大幅减少数据类的样板代码,提高开发效率和代码可读性。
time模块
import time as _time_mod 是 Python 中一种常见的别名导入方式,主要目的是重命名导入的模块,以便在代码中用一个更短或更明确的名称引用它。这里的别名 _time_mod 前面有一个下划线,在 Python 命名约定中表示"内部使用"或"私有"的意图。
使用别名 _time_mod的原因
- 避免命名冲突
- 表明私有/内部使用
- 简洁或语义化
time 模块常用功能
| 函数/属性 | 描述 |
|---|---|
time() |
返回当前时间戳(浮点数,秒为单位,从 epoch 开始) |
sleep(secs) |
暂停当前线程执行指定的秒数 |
perf_counter() |
高精度性能计数器(常用于测量短时间间隔) |
localtime([secs]) |
将时间戳转换为本地时间的 struct_time 对象 |
strftime(format[, t]) |
将时间元组格式化为字符串 |
1. time.time()
返回当前时间的时间戳(浮点数),单位是秒。时间戳是从 epoch(1970年1月1日 00:00:00 UTC)开始经过的秒数。常用于计算一段代码的运行时间(结合前后两次 time.time() 的差值)。
python
import time
now = time.time()
print(now)
print(type(now))
执行结果:
python
1775719307.6961381
<class 'float'>
2. time.sleep(secs)
让当前线程暂停执行 secs 秒,可以是浮点数(支持亚秒级暂停)。常用于模拟耗时操作、控制循环频率、等待外部资源等。
python
print("start...")
time.sleep(2.5) # 暂停 2.5 秒
print("Stop")
3. time.perf_counter()
提供高精度性能计数器,最适合测量短时间间隔。它使用系统上可用的最高精度的时钟(如 CPU 计时器),不受系统时间调整(如 NTP 同步)的影响。perf_counter() 专门用于性能测量,单调递增,精度更高。
python
start = time.perf_counter()
# 执行一些操作,例如求和
sum(range(1_000_000))
end = time.perf_counter()
print(f"耗时 {end - start:.6f} 秒")
执行结果:
python
耗时 0.013896 秒
4. time.localtime([secs])
将一个时间戳(默认使用当前时间 time.time())转换为本地时间的 struct_time 对象。该对象包含年、月、日、时、分、秒、星期几等属性。
python
import time
# 不传参数,使用当前时间戳
local = time.localtime()
print(local)
print("="*50)
# time.struct_time(tm_year=2024, tm_mon=4, tm_mday=9, tm_hour=15, ...)
print(local.tm_year)
print(local.tm_mon)
print(local.tm_hour)
print("="*50)
# 传入指定时间戳(例如 0 表示 epoch 时间)
epoch_local = time.localtime(0)
print(epoch_local)
运行结果:
python
time.struct_time(tm_year=2026, tm_mon=4, tm_mday=9, tm_hour=15, tm_min=32, tm_sec=46, tm_wday=3, tm_yday=99, tm_isdst=0)
==================================================
2026
4
15
==================================================
time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1, tm_hour=8, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=1, tm_isdst=0)
5. time.strftime(format[, t])
将 struct_time 对象(默认使用 localtime() 的当前时间)格式化为自定义字符串。format 使用 % 指令,例如 %Y 表示四位年份,%m 表示两位月份等。
python
# 格式化当前时间
now_str = time.strftime("%Y-%m-%d %H:%M:%S")
print(now_str)
# 格式化指定的 struct_time
some_time = time.localtime(0) # epoch 时间
formatted = time.strftime("%Y年%m月%d日 %H:%M:%S", some_time)
print(formatted)
运行结果:
python
2026-04-09 15:35:37
1970年01月01日 08:00:00