当前位置: 首页 > news >正文

2025-10-08 Python 标准库 9——内置类型:其他

文章目录

  • 1. 上下文管理器类型
    • 1.1. 上下文管理器的核心协议
      • 1.1.1. `__enter__()`
      • 1.1.2. `__exit__(exc_type, exc_val, exc_tb)`
    • 1.3. `contextlib.contextmanager` 装饰器
    • 1.4. 常见内置上下文管理器
  • 2. 类型注解:Generic Alias 与 Union
    • 2.1. Generic Alias(泛型别名)
    • 2.2. Union(联合类型)
  • 3. 其他内置类型
    • 3.1. 模块(Module)
    • 3.2. 函数(Function)
    • 3.3. 方法(Method)
    • 3.4. 特殊对象
      • 3.4.1. 空对象(None)
      • 3.4.2. 省略符(Ellipsis,`...`)
      • 3.4.3. 未实现对象(NotImplemented)
  • 4. 整数字符串转换长度限制(Python 3.11+)
    • 4.1. 限制范围
    • 4.2. 配置限制的方式
    • 4.3. 注意事项
  • 5. 总结

参考文档:内置类型 — Python 3.13.8 文档

1. 上下文管理器类型

在 Python 中,上下文管理器是支持 with 语句的核心机制,用于定义代码块的“运行时上下文”——即代码块执行前的初始化操作(如打开文件、获取锁)和执行后的清理操作(如关闭文件、释放锁),无需手动管理资源,避免遗漏清理步骤导致的问题(如文件句柄泄漏)。

1.1. 上下文管理器的核心协议

一个对象要成为上下文管理器,必须实现 __enter__()__exit__() 两个特殊方法,这两个方法共同定义了 with 语句的执行逻辑。

1.1.1. __enter__()

  • 作用:进入上下文时执行(with 语句块执行前),负责初始化资源(如打开文件、创建连接)。
  • 返回值:会绑定到 with 语句的 as 子句变量(若指定),通常返回上下文管理器自身或关联资源(如文件对象)。
  • 示例场景:文件对象的 __enter__() 返回自身,因此 with open('file.txt') as ff 就是文件对象。

1.1.2. __exit__(exc_type, exc_val, exc_tb)

  • 作用:退出上下文时执行(with 语句块执行后,无论是否发生异常),负责清理资源(如关闭文件、释放锁)。
  • 参数说明
    • exc_type:若语句块执行时发生异常,为异常类型(如 ValueError);否则为 None
    • exc_val:若发生异常,为异常实例;否则为 None
    • exc_tb:若发生异常,为异常的回溯对象(traceback);否则为 None
  • 返回值:布尔值,True 表示屏蔽语句块中发生的异常(不向外传播),False 表示不屏蔽(异常继续传播)。注意:不建议显式重新抛出异常,通过返回值控制即可

通过自定义类实现 __enter__()__exit__(),可创建符合业务需求的上下文管理器。以下示例实现一个“文件读写上下文管理器”,自动处理文件打开与关闭:

class FileManager:def __init__(self, file_path, mode='r'):"""初始化:接收文件路径和打开模式"""self.file_path = file_pathself.mode = modeself.file = None  # 初始化文件对象为Nonedef __enter__(self):"""进入上下文:打开文件并返回文件对象"""print(f"打开文件:{self.file_path}")self.file = open(self.file_path, self.mode, encoding='utf-8')return self.file  # 绑定到as子句变量def __exit__(self, exc_type, exc_val, exc_tb):"""退出上下文:关闭文件,处理异常"""if self.file:  # 确保文件已打开print(f"关闭文件:{self.file_path}")self.file.close()# 处理异常(示例:打印异常信息但不屏蔽)if exc_type is not None:print(f"执行异常:{exc_type.__name__}: {exc_val}")return False  # 不屏蔽异常,让异常向外传播# 使用自定义上下文管理器
try:with FileManager('test.txt', 'w') as f:f.write("Hello, 上下文管理器!")# 故意触发异常(测试__exit__是否执行)raise ValueError("测试异常传播")
except ValueError as e:print(f"捕获外部异常:{e}")# 输出结果:
# 打开文件:test.txt
# 关闭文件:test.txt
# 执行异常:ValueError: 测试异常传播
# 捕获外部异常:测试异常传播

关键结论:即使 with 语句块中发生异常,__exit__() 仍会执行(确保文件关闭),体现了上下文管理器的“资源安全管理”核心价值。

1.3. contextlib.contextmanager 装饰器

手动实现 __enter__()__exit__() 略显繁琐,Python 提供 contextlib.contextmanager 装饰器,可通过生成器函数快速创建上下文管理器,无需定义类。

其原理是:

  • 生成器函数中,yield 之前的代码对应 __enter__() 的逻辑(初始化资源);
  • yield 的返回值对应 __enter__() 的返回值(绑定到 as 子句);
  • yield 之后的代码对应 __exit__() 的逻辑(清理资源)。

示例:用装饰器实现“计时上下文管理器”

from contextlib import contextmanager
import time@contextmanager
def timer(name="操作"):"""计时上下文管理器:统计代码块执行时间"""# 1. 进入上下文:记录开始时间(对应__enter__)start_time = time.time()print(f"[{name}] 开始执行...")# 2. yield:返回开始时间(绑定到as子句),暂停等待代码块执行yield start_time# 3. 退出上下文:计算并打印耗时(对应__exit__)end_time = time.time()print(f"[{name}] 执行完成,耗时:{end_time - start_time:.4f}秒")# 使用计时上下文管理器
with timer("循环计算") as start:# 模拟耗时操作total = 0for i in range(1_000_000):total += i# 输出结果:
# [循环计算] 开始执行...
# [循环计算] 执行完成,耗时:0.0456秒

优势:代码更简洁,无需手动处理异常(装饰器会自动捕获异常并确保 yield 后的清理代码执行)。

1.4. 常见内置上下文管理器

Python 内置了多个实用的上下文管理器,无需自定义即可直接使用:

  • 文件对象with open('file.txt') as f,自动关闭文件;
  • 线程锁with threading.Lock(),自动获取和释放锁;
  • decimal 上下文with decimal.localcontext(),临时修改十进制计算上下文;
  • suppress 上下文with contextlib.suppress(ValueError),屏蔽指定异常(避免 try-except)。

示例:使用 suppress 屏蔽异常

from contextlib import suppress# 屏蔽ValueError,无需try-except
with suppress(ValueError):int("abc")  # 转换失败,抛出ValueError,但被suppress屏蔽
print("程序继续执行(未崩溃)")  # 正常输出

2. 类型注解:Generic Alias 与 Union

Python 3.9+ 引入了原生的类型注解类型,用于更简洁、直观地标注变量和函数的类型,替代早期 typing 模块中的 List[int]Union[int, str] 等写法。核心类型包括 Generic Alias(泛型别名)和 Union(联合类型)。

2.1. Generic Alias(泛型别名)

Generic Alias 是通过“类抽取”创建的泛型类型(如 list[int]dict[str, int]),主要用于类型标注,明确容器类(如列表、字典)中元素的具体类型,帮助静态类型检查工具(如 mypy)识别类型错误,提升代码可读性。

  • 核心特点
    1. 基于现有类创建(如 listlist[int]),需类实现 __class_getitem__() 方法;
    2. 仅用于类型标注,运行时不强制执行类型检查(Python 是动态类型语言);
    3. 支持嵌套(如 list[dict[str, int]] 表示“元素为字典的列表,字典的键是字符串、值是整数”)。

创建与使用示例

# 1. 标注列表类型:元素为float
def average(values: list[float]) -> float:"""计算列表中浮点数的平均值"""return sum(values) / len(values)# 2. 标注字典类型:键为str,值为list[int]
def count_words(sentences: list[str]) -> dict[str, int]:"""统计每个单词出现的次数"""word_count = {}for sent in sentences:for word in sent.split():word_count[word] = word_count.get(word, 0) + 1return word_count# 3. 嵌套泛型:list[dict[str, list[int]]]
def group_scores(students: list[dict[str, list[int]]]) -> dict[str, int]:"""按学生姓名分组,计算总分"""total_scores = {}for student in students:name = student["name"]scores = student["scores"]total_scores[name] = sum(scores)return total_scores# 测试(运行时不检查类型,仅标注)
scores = [{"name": "Alice", "scores": [85, 92]}, {"name": "Bob", "scores": [78, 88]}]
print(group_scores(scores))  # 输出:{'Alice': 177, 'Bob': 166}

关键属性:__origin____args__

Generic Alias 对象有两个只读属性,用于查看其原始类型和参数:

  • __origin__:返回未带参数的原始类(如 list[int].__origin__list);
  • __args__:返回泛型参数的元组(如 dict[str, int].__args__(str, int))。
# 查看泛型别名的属性
lst_type = list[int]
print(lst_type.__origin__)  # 输出:<class 'list'>(原始类)
print(lst_type.__args__)    # 输出:(int,)(泛型参数)dict_type = dict[str, list[float]]
print(dict_type.__origin__)  # 输出:<class 'dict'>
print(dict_type.__args__)    # 输出:(<class 'str'>, list[float])(嵌套参数)

注意事项

  1. 运行时类型擦除list[str]() 创建的对象类型仍是 list,而非 list[str],泛型参数仅在标注阶段有效;

    t = list[str]
    l = t()
    print(type(l))  # 输出:<class 'list'>(类型擦除)
    
  2. isinstance 不支持:不能用 isinstance([1, 2], list[int]) 检查,会抛出 TypeError

    # 错误用法
    # isinstance([1, 2], list[int])  # 报错:TypeError: isinstance() argument 2 cannot be a parameterized generic
    

Python 标准库中多个类支持泛型别名,常见的包括:

容器类泛型别名示例含义
listlist[int]元素为整数的列表
dictdict[str, bool]键为字符串、值为布尔的字典
setset[bytes]元素为字节的集合
tupletuple[str, int]第一个元素为字符串、第二个为整数的元组
collections.dequedeque[float]元素为浮点数的双端队列
re.Matchre.Match[str]匹配结果为字符串的正则匹配对象

2.2. Union(联合类型)

Union 表示“多个类型中的任意一个”,使用 | 运算符创建(Python 3.10+ 支持),替代早期 typing.Union[int, str] 的写法,用于标注变量或参数可能为多种类型的场景(如“整数或浮点数”“字符串或 None”)。

  • 核心特点
    1. 自动平推与去重:(int | str) | float 等价于 int | str | floatint | int | str 等价于 int | str
    2. 顺序无关:int | strstr | int 完全等价;
    3. Optional 兼容:str | None 等价于 typing.Optional[str](表示“可选类型,可为 None”)。

基础使用:标注多类型参数

# 1. 标注“整数或浮点数”类型的参数
def square(number: int | float) -> int | float:"""计算一个数的平方,支持整数或浮点数"""return number ** 2# 2. 标注“字符串或None”(等价于Optional[str])
def greet(name: str | None) -> str:"""根据姓名打招呼,name为None时使用默认值"""if name is None:name = "Guest"return f"Hello, {name}!"# 3. 嵌套Union:“列表或字典,元素为整数或字符串”
def process_data(data: list[int | str] | dict[str, int | str]) -> None:"""处理数据:支持列表或字典"""if isinstance(data, list):print("处理列表:", [str(x) for x in data])else:print("处理字典:", {k: str(v) for k, v in data.items()})# 测试
print(square(5))          # 输出:25(int)
print(square(3.2))        # 输出:10.24(float)
print(greet(None))        # 输出:Hello, Guest!
process_data([1, "a", 3]) # 输出:处理列表:['1', 'a', '3']
process_data({"a": 1, "b": "2"}) # 输出:处理字典:{'a': '1', 'b': '2'}

isinstance 支持

Generic Alias 不同,Union 支持 isinstanceissubclass 检查(但不支持包含 Generic AliasUnion,如 int | list[int]):

# 正确:检查变量是否为int或str
x = 123
print(isinstance(x, int | str))  # 输出:Truey = "abc"
print(isinstance(y, int | str))  # 输出:True# 错误:Union包含Generic Alias(list[int]),不支持isinstance
# z = [1, 2]
# print(isinstance(z, int | list[int]))  # 报错:TypeError: isinstance() argument 2 cannot be a parameterized generic

typing.Union 的兼容性

| 运算符创建的 Uniontyping.Union 完全等价,可混合使用:

from typing import Union# 两种写法等价
print(int | str == Union[int, str])  # 输出:True
print(str | None == Union[str, None])# 输出:True(等价于Optional[str])

3. 其他内置类型

Python 解释器还支持多种特殊内置类型,这些类型通常仅支持有限操作,用于特定场景(如模块、函数、方法、代码对象等)。

3.1. 模块(Module)

  • 概念:模块是 Python 代码的组织单元,一个 .py 文件就是一个模块,用于封装变量、函数、类等。

  • 核心操作

    1. 属性访问module.name(如 sys.pathos.path);
    2. 动态修改:通过 module.__dict__ 访问模块的符号表(不建议直接修改)。
    import sys# 访问模块属性
    print(sys.version)  # 输出:Python版本(如3.11.4 (main, Jun 12 2023, 15:19:37) [GCC 11.2.0])
    print(sys.path)    # 输出:模块搜索路径列表# 查看模块符号表(__dict__)
    print("sys模块中的前5个符号:", list(sys.__dict__.keys())[:5])
    # 输出:sys模块中的前5个符号:['__name__', '__doc__', '__package__', '__loader__', '__spec__']
    

3.2. 函数(Function)

  • 概念:通过 def 定义的可调用对象,支持参数传递和返回值。

  • 分类

    1. 用户自定义函数def func(): ...
    2. 内置函数print()len() 等(由 C 实现,效率更高)。
  • 核心操作:仅支持调用func(args)),可通过 __name____doc__ 等属性查看函数信息。

    # 自定义函数
    def add(a: int, b: int) -> int:"""计算两个整数的和"""return a + b# 查看函数属性
    print(add.__name__)  # 输出:add(函数名)
    print(add.__doc__)   # 输出:计算两个整数的和(文档字符串)
    print(add(2, 3))     # 输出:5(函数调用)# 内置函数
    print(len([1, 2, 3]))  # 输出:3(内置函数调用)
    

3.3. 方法(Method)

  • 概念:绑定到类或实例的函数,分为实例方法类方法静态方法

  • 关键特性

    1. 实例方法:第一个参数为 self,绑定到实例(如 list.append());
    2. 类方法:用 @classmethod 装饰,第一个参数为 cls,绑定到类;
    3. 静态方法:用 @staticmethod 装饰,不绑定到类或实例,无默认参数。
    class MyClass:count = 0  # 类属性def __init__(self, name: str):self.name = name  # 实例属性MyClass.count += 1# 实例方法:绑定到实例def get_name(self) -> str:return self.name# 类方法:绑定到类@classmethoddef get_count(cls) -> int:return cls.count# 静态方法:不绑定@staticmethoddef add(a: int, b: int) -> int:return a + b# 实例方法调用(绑定到实例)
    obj = MyClass("Alice")
    print(obj.get_name())  # 输出:Alice(自动传入self)# 类方法调用(绑定到类)
    print(MyClass.get_count())  # 输出:1(自动传入cls)# 静态方法调用(无绑定)
    print(MyClass.add(2, 3))  # 输出:5(无需传入self/cls)
    

3.4. 特殊对象

3.4.1. 空对象(None)

  • 概念:表示“无值”的单例对象,仅一个实例(None),用于表示函数无返回值、变量未赋值等。

  • 特性

    1. 类型为 NoneTypetype(None) 可获取类型;
    2. 仅支持 is/is not 比较(不建议用 ==)。
    # 函数无返回值,默认返回None
    def func():print("无返回值")result = func()
    print(result is None)  # 输出:True# 变量未赋值时用None初始化
    name: str | None = None
    if name is None:name = "Bob"
    print(name)  # 输出:Bob
    

3.4.2. 省略符(Ellipsis,...

  • 概念:表示“省略内容”的单例对象,写法为 Ellipsis...

  • 常见用途

    1. 类型标注:如 tuple[int, ...] 表示“元素为整数的变长元组”;
    2. NumPy 切片:如 arr[..., 0] 表示“所有维度的第 0 列”;
    3. 替代 pass:作为空代码块的占位符。
    # 1. 类型标注:变长元组
    def sum_tuple(numbers: tuple[int, ...]) -> int:return sum(numbers)print(sum_tuple((1, 2, 3)))  # 输出:6
    print(sum_tuple((4,)))       # 输出:4# 2. 替代pass
    class EmptyClass:...  # 等价于pass# 3. NumPy切片(需安装numpy)
    # import numpy as np
    # arr = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]])
    # print(arr[..., 0])  # 输出:[[1 3], [5 7]]
    

3.4.3. 未实现对象(NotImplemented)

  • 概念:表示“操作未实现”的单例对象,用于运算符重载时告知解释器“该操作需由其他对象处理”。

  • 示例:在类中重载 __add__,未支持的类型返回 NotImplemented

    class MyNumber:def __init__(self, value: int):self.value = value# 重载加法运算符def __add__(self, other):if isinstance(other, MyNumber):return MyNumber(self.value + other.value)# 不支持的类型,返回NotImplemented,让解释器尝试other.__radd__(self)return NotImplementeddef __repr__(self):return f"MyNumber({self.value})"# 支持的类型:MyNumber + MyNumber
    a = MyNumber(2)
    b = MyNumber(3)
    print(a + b)  # 输出:MyNumber(5)# 不支持的类型:MyNumber + int(返回NotImplemented,最终抛TypeError)
    try:print(a + 5)
    except TypeError as e:print(e)  # 输出:unsupported operand type(s) for +: 'MyNumber' and 'int'
    

4. 整数字符串转换长度限制(Python 3.11+)

Python 3.11 引入了整数字符串转换长度限制,用于缓解“超长数字字符串转换导致的拒绝服务(DoS)攻击”——例如转换 '1' * 1_000_000 这类超长字符串会消耗大量 CPU 资源,限制可避免此类问题。

4.1. 限制范围

  • 作用场景:仅对非 2 的幂次基数的转换生效(如十进制 int('123')),对 2、4、8、16、32 等基数的转换无限制(算法为线性,效率高)。
  • 受影响的 API
    1. int(string)(默认十进制);
    2. str(integer)repr(integer)(十进制字符串转换);
    3. 格式化字符串:f"{integer}""{}.format(integer)"
  • 默认限制:4300 位数字(可通过 sys.int_info.default_max_str_digits 查看),超过限制会抛出 ValueError
import sys# 查看默认限制
print("默认整数字符串转换限制:", sys.int_info.default_max_str_digits)  # 输出:4300# 1. 触发限制:转换4301位的数字字符串
long_str = '2' * 4301
try:int(long_str)
except ValueError as e:print("触发限制错误:", e)# 输出:触发限制错误:Exceeds the limit (4300 digits) for integer string conversion: value has 4301 digits; use sys.set_int_max_str_digits() to increase the limit# 2. 调整限制:临时提高上限(需谨慎,避免DoS风险)
sys.set_int_max_str_digits(5000)  # 设为5000位
print(int('2' * 4500))  # 成功转换,无报错# 3. 禁用限制(不推荐,仅在信任输入时使用)
# sys.set_int_max_str_digits(0)  # 0表示禁用限制

4.2. 配置限制的方式

除了代码中用 sys.set_int_max_str_digits() 调整,还可通过以下方式配置:

  1. 环境变量PYTHONINTMAXSTRDIGITS=5000 python script.py
  2. 命令行参数python -X int_max_str_digits=5000 script.py
  3. 子解释器:子解释器有独立的限制,需单独配置。

4.3. 注意事项

  • 最低限制:不可低于 640 位(sys.int_info.str_digits_check_threshold),低于会抛出 ValueError
  • 绕过限制:若需处理超长数字,可使用十六进制(如 int('ff' * 1000, 16)),因 16 是 2 的幂次,无限制;
  • 谨慎禁用:禁用限制(设为 0)仅适用于完全信任输入的场景,否则可能面临 DoS 风险。

5. 总结

  1. 上下文管理器:通过 __enter__()/__exit__()contextlib 装饰器实现,核心是安全管理资源(如文件、锁),避免手动清理遗漏;
  2. 类型注解类型Generic Alias(如 list[int])用于标注容器元素类型,Union(如 int | str)用于标注多类型场景,提升代码可读性和静态检查能力;
  3. 其他内置类型:模块、函数、方法等是 Python 代码组织的基础,None...NotImplemented 等特殊对象用于特定场景,需理解其单例特性和使用限制;
  4. 整数字符串限制:Python 3.11+ 新增的安全机制,需注意受影响的 API 和配置方式,避免超长输入导致性能问题。
http://www.dtcms.com/a/457114.html

相关文章:

  • Oracle实战:相同批次下D5_D10最新数据整合为一行的3种方案
  • 私人精品货源网站有哪些php网站开发前端
  • 金融 - 搭建 图谱挖掘工作流 调研
  • 图像分割关于DualSeg,FFM和CFM的论文学习
  • Spring的 `@Import`注解 笔记251008
  • 【玩泰山派】4、制作ubuntu镜像-(6)使用鲁班猫的sdk去制作镜像
  • 长兴县住房和城乡建设局网站我想看黄牌
  • 深入理解 Reactor 反应堆模式:高性能网络编程的核心
  • php做小公司网站用什么框架医药招商网站大全免费
  • 从 0 到 1 掌控云原生部署:Java 项目的 Docker 容器化与 K8s 集群实战指南
  • 哪里可以做足球网站虚拟主机 2个网站
  • 建设银行的英语网站首页dede导入wordpress
  • 支付宝小程序 MAU 增长新路径:生态工具与流量闭环的协同实战
  • C++ 成员初始化列表
  • 三门县住房和城乡建设规划局网站商业网站是怎么做的
  • Spring Security 最简配置完全指南-从入门到精通前后端分离安全配置
  • Go泛型实战指南:从入门到工程最佳实践|Go语言进阶(12)
  • easyexcel实现excel读取
  • 用jsp实现网站开发实例高校网站站群建设公司
  • 个人网站导航html源码团购网站模板
  • wpf之RelativeSource用法总结
  • 【C语言基础详细版】06. 动态内存管理:从原理到实战应用
  • 磁悬浮轴承转子不平衡质量控制深度解析
  • 关于力扣2025.10.8每日的收货
  • 烟台做网站的价格网络工程是冷门专业吗
  • 亲测可用,R语言 ggplot2 箱线图线条控制参数详解,箱线图离散数值控制
  • 沙漠风网站建设公司太原不错的互联网公司
  • 记录thinkphp模型查询时select与count执行顺序的疑问
  • AI编写的一个服务器监控源码
  • C# TCP 客户端开发笔记(TcpClient)