文章目录
- 限制函数参数只能取 “success”/“failure”/“pending” 三个值: from typing import Literal def print_task_status(status: Literal[“success”, “failure”, “pending”]) -> None: “””打印任务状态,仅接受指定的3个值””” print(f”Task status: {status}”) 合法调用(符合字面量限制) print_task_status(“success”) print_task_status(“pending”) 非法调用(超出字面量范围,静态检查工具会报错) print_task_status(“error”) # mypy 提示:Argument 1 to “print_task_status” has incompatible type “Literal[‘error’]”; expected “Literal[‘success’, ‘failure’, ‘pending’]”
- 限制参数只能取 1/2/3(比如代表日志级别): from typing import Literal def set_log_level(level: Literal[1, 2, 3]) -> None: “””设置日志级别:1=DEBUG,2=INFO,3=ERROR””” level_map = {1: “DEBUG”, 2: “INFO”, 3: “ERROR”} print(f”Log level set to: {level_map[level]}”) 合法调用 set_log_level(2) 非法调用(mypy 报错) set_log_level(4) # 超出 1/2/3 范围
- Literal 支持不同类型的字面量混合(但不推荐,易增加代码复杂度): from typing import Literal def get_config(key: Literal[“timeout”, “retry”, 5]) -> str: “””获取配置,key 仅支持指定字符串/数值””” config = {“timeout”: “10s”, “retry”: “3次”, 5: “特殊配置”} return config[key] 合法调用 get_config(“timeout”) get_config(5) 非法调用 get_config(6) # mypy 报错
- 如果字面量列表较长,可通过 TypeAlias 定义别名,提升代码可读性: from typing import Literal, TypeAlias #定义类型别名:限制仅支持这4种HTTP方法 HTTPMethod: TypeAlias = Literal[“GET”, “POST”, “PUT”, “DELETE”] def send_request(url: str, method: HTTPMethod) -> None: “””发送HTTP请求,method 仅支持指定方法””” print(f”Send {method} request to {url}”) 合法调用 send_request(“https://example.com”, “GET”) 非法调用 send_request(“https://example.com”, “PATCH”) # mypy 报错
- Literal 仅作用于静态类型检查(如 mypy),不会自动拦截运行时的非法值!如果需要运行时校验,需手动添加逻辑: from typing import Literal def print_status(status: Literal[“success”, “failure”, “pending”]) -> None: # 运行时校验(兜底) valid_status = {“success”, “failure”, “pending”} if status not in valid_status: raise ValueError(f”Invalid status: {status}. Must be one of {valid_status}”) print(status) #运行时触发报错 print_status(“error”) # ValueError: Invalid status: error. Must be one of {‘success’, ‘failure’, ‘pending’}
- Python 3.8+:直接从 typing 导入 Literal; Python 3.7 及以下:需安装 typing_extensions,并从该库导入: #Python 3.7- from typing_extensions import Literal
- 编写代码后,通过 mypy 校验类型
目录
- 一、基础使用步骤
- 二、实战示例
- 示例 1:限制字符串字面量
- 示例 2:限制数值字面量
- 示例 3:混合类型字面量(慎用)
- 示例 4:结合类型别名(简化复杂字面量)
- 三、关键注意事项
- 1.运行时校验(重要)
- 2.版本兼容
- 3.配合静态检查工具
- 检查当前文件(假设文件名为 test.py)
- 四、应用场景
Literal 是 Python 类型提示(Type Hint)中的核心工具,用于严格限制变量 / 函数参数只能取指定的字面量值,结合静态类型检查工具(如 mypy)可提前拦截非法值传入,大幅提升代码健壮性。以下是完整的使用方法和示例:
环境准备
- Python 3.8+:Literal 首次内置在 typing 模块中;
- Python 3.7 及以下:需安装 typing_extensions 库(pip install typing-extensions),从 typing_extensions 导入;
- 静态检查工具(可选但推荐):安装 mypy(pip install mypy),用于校验类型合规性。
核心语法
Python 3.8+
from typing import Literal
Python 3.7-
from typing_extensions import Literal
def 函数名(参数名: Literal[值1, 值2, 值3, …]) -> 返回值类型:
函数逻辑
限制函数参数只能取 “success”/“failure”/“pending” 三个值:
from typing import Literal
def print_task_status(status: Literal["success", "failure", "pending"]) -> None:
"""打印任务状态,仅接受指定的3个值"""
print(f"Task status: {status}")
合法调用(符合字面量限制)
print_task_status(“success”) print_task_status(“pending”)
非法调用(超出字面量范围,静态检查工具会报错)
print_task_status("error") # mypy 提示:Argument 1 to "print_task_status" has incompatible type "Literal['error']"; expected "Literal['success', 'failure', 'pending']"
限制参数只能取 1/2/3(比如代表日志级别):
from typing import Literal
def set_log_level(level: Literal[1, 2, 3]) -> None:
"""设置日志级别:1=DEBUG,2=INFO,3=ERROR"""
level_map = {1: "DEBUG", 2: "INFO", 3: "ERROR"}
print(f"Log level set to: {level_map[level]}")
合法调用
set_log_level(2)
非法调用(mypy 报错)
set_log_level(4) # 超出 1/2/3 范围
Literal 支持不同类型的字面量混合(但不推荐,易增加代码复杂度):
from typing import Literal
def get_config(key: Literal["timeout", "retry", 5]) -> str:
"""获取配置,key 仅支持指定字符串/数值"""
config = {"timeout": "10s", "retry": "3次", 5: "特殊配置"}
return config[key]
合法调用
get_config(“timeout”) get_config(5)
非法调用
get_config(6) # mypy 报错
如果字面量列表较长,可通过 TypeAlias 定义别名,提升代码可读性:
from typing import Literal, TypeAlias
#定义类型别名:限制仅支持这4种HTTP方法
HTTPMethod: TypeAlias = Literal["GET", "POST", "PUT", "DELETE"]
def send_request(url: str, method: HTTPMethod) -> None:
"""发送HTTP请求,method 仅支持指定方法"""
print(f"Send {method} request to {url}")
合法调用
send_request(“https://example.com”, “GET”)
非法调用
send_request(“https://example.com”, “PATCH”) # mypy 报错
Literal 仅作用于静态类型检查(如 mypy),不会自动拦截运行时的非法值!如果需要运行时校验,需手动添加逻辑:
from typing import Literal
def print_status(status: Literal["success", "failure", "pending"]) -> None:
# 运行时校验(兜底)
valid_status = {"success", "failure", "pending"}
if status not in valid_status:
raise ValueError(f"Invalid status: {status}. Must be one of {valid_status}")
print(status)
#运行时触发报错
print_status("error") # ValueError: Invalid status: error. Must be one of {'success', 'failure', 'pending'}
- Python 3.8+:直接从 typing 导入 Literal;
- Python 3.7 及以下:需安装 typing_extensions,并从该库导入:
#Python 3.7-
from typing_extensions import Literal
编写代码后,通过 mypy 校验类型
mypy test.py
若存在非法参数传入,mypy 会输出明确的错误提示,提前发现问题。
- 配置项限制:如环境(dev/test/prod)、日志级别(DEBUG/INFO/ERROR);
- 接口参数限制:如 HTTP 方法、数据库操作类型(read/write);
- 状态机限制:如任务状态(pending/running/finished)。
通过 Literal 限制参数范围,既能让代码意图更清晰,也能借助工具提前规避非法值传入的问题,是 Python 类型提示中提升代码可靠性的重要手段。
到此这篇关于浅析python如何使用Literal类型来限制函数参数的取值范围的文章就介绍到这了,更多相关python Literal类型限制函数参数内容请搜索风君子博客以前的文章或继续浏览下面的相关文章希望大家以后多多支持风君子博客!
您可能感兴趣的文章:
- Python中Literal 类型的具体使用
- python中literal_eval函数的使用小结
- Python eval()函数和ast.literal_eval()的区别你知道吗
- Python中函数eval和ast.literal_eval的区别详解
- Python ValueError: invalid literal for int() with base 10 实用解决方法
- Python EOL while scanning string literal问题解决方法