在 Python 中,__args__ 是一个特殊属性,通常与 类型提示(Type Hints) 和泛型(Generics)相关,它主要用于访问泛型类型的参数。
什么是 __args__?
__args__ 是 typing 模块中泛型类型对象的一个属性,用于存储泛型中指定的具体类型参数。
from typing import List, Dict # 定义一个泛型类型 MyList = List[int] MyDict = Dict[str, int] # 访问 __args__ print(MyList.__args__) # 输出: (<class 'int'>,) print(MyDict.__args__) # 输出: (<class 'str'>, <class 'int'>)
常见使用场景
✅ 场景 1:检查或提取泛型类型参数
当你需要动态检查一个类型是否是泛型,并提取其内部类型时,__args__ 非常有用。
from typing import List, Optional, Union
def get_generic_args(type_hint):
"""安全地获取泛型类型的参数"""
if hasattr(type_hint, '__args__'):
return type_hint.__args__
return None
# 示例
print(get_generic_args(List[int])) # 输出: (<class 'int'>,)
print(get_generic_args(Optional[str])) # 输出: (<class 'str'>, <class 'NoneType'>)
print(get_generic_args(Union[int, str])) # 输出: (<class 'int'>, <class 'str'>)
print(get_generic_args(int)) # 输出: None (非泛型类型)
✅ 场景 2:在装饰器或元类中处理类型
在编写高级框架(如 FastAPI、Pydantic、SQLAlchemy 等)时,经常需要解析函数参数或模型字段的类型,__args__ 是关键工具。
from typing import List
import inspect
def analyze_function(func):
sig = inspect.signature(func)
for param_name, param in sig.parameters.items():
if param.annotation != inspect.Parameter.empty:
ann = param.annotation
if hasattr(ann, '__args__'):
print(f"参数 '{param_name}' 是泛型类型: {ann}")
print(f" 类型参数: {ann.__args__}")
else:
print(f"参数 '{param_name}' 是普通类型: {ann}")
def my_function(items: List[int], name: str):
pass
analyze_function(my_function)
# 输出:
# 参数 'items' 是泛型类型: typing.List[int]
# 类型参数: (<class 'int'>,)
# 参数 'name' 是普通类型: <class 'str'>
注意事项
⚠️ Python 3.9+ 的新语法
从 Python 3.9 开始,内置集合类型(如 list, dict, tuple)可以直接用于类型提示,不再需要导入 typing 模块。
# Python 3.9+ MyList = list[int] print(MyList.__args__) # 输出: (<class 'int'>,)
注意:
list[int]和List[int]在__args__行为上是一致的。
⚠️ __origin__ 属性
除了 __args__,泛型类型通常还有一个 __origin__ 属性,表示原始类型(如 list, dict 等)。
from typing import List MyList = List[int] print(MyList.__origin__) # 输出: <class 'list'> print(MyList.__args__) # 输出: (<class 'int'>,)
⚠️ 嵌套泛型
对于嵌套泛型,__args__ 会递归地包含其他泛型对象。
from typing import List, Dict Nested = List[Dict[str, int]] print(Nested.__args__) # 输出: (typing.Dict[str, int],) # 注意:第一个元素本身是一个泛型类型,可以继续访问其 __args__ print(Nested.__args__[0].__args__) # 输出: (<class 'str'>, <class 'int'>)
安全获取 __args__ 的最佳实践
由于并非所有类型都有 __args__ 属性(例如普通类、基本类型),建议始终使用 hasattr 或 getattr 来安全访问:
from typing import get_args, get_origin # Python 3.8+ 推荐方式 # 更现代、更安全的做法是使用 typing 模块提供的工具函数 from typing import List MyList = List[int] # 使用 get_args 和 get_origin print(get_args(MyList)) # 输出: (<class 'int'>,) print(get_origin(MyList)) # 输出: <class 'list'> # 对于普通类型 print(get_args(int)) # 输出: () print(get_origin(int)) # 输出: None
推荐:在 Python 3.8+ 中,优先使用
typing.get_args()和typing.get_origin(),它们比直接访问__args__和__origin__更安全、更清晰。
__args__是泛型类型的属性,存储类型参数。- 常用于动态类型检查、框架开发、反射。
- Python 3.8+ 推荐使用
typing.get_args()和typing.get_origin()作为更安全、更标准的替代方案。
首发原创文章,作者:世雄 - 原生数据库架构专家,如若转载,请注明出处:https://idctop.com/article/477954.html



