前言
利用typing模块可以让代码更加专业,增加代码的可读性和可维护性。
一、主要用途
1. 类型注解:
typing 模块定义了许多类型注解,比如 List, Dict, Tuple, Set, Optional, Union, TypeVar, Callable 等。
这些注解可以帮助开发者更清楚地表达函数的参数类型和返回类型。
2. 类型提示:
类型注解可以用作类型提示,使 IDE 和编辑器能够更好地理解代码结构,从而提供更好的代码补全和错误检测功能。
类型提示还可以帮助其他开发者更快地理解代码的功能和用法。
3. 静态类型检查:
类型注解可以与第三方类型检查工具(如 Mypy)一起使用,以在运行之前检查代码中的类型错误。
这有助于减少运行时错误,并提高代码质量。
二、typing 模块中的一些常用类型
1. List:
用于表示列表类型,例如 List[int]
表示整数列表。
2. Dict:
用于表示字典类型,例如 Dict[str, int]
表示键为字符串
、值为整数的字典
。
3. Tuple:
用于表示元组类型,例如 Tuple[int, str]
表示第一个
元素为整数、第二个
元素为字符串的元组。
4. Optional:
用于表示一个变量可以是某个类型也可以是 None,例如 Optional[str]
表示变量可以是字符串
或 None
。 例如:prompt: Optional[str] = None:
表示该参数可以是一个字符串 (str) 或者 None。`默认值: 默认值为 None
5. Union:
用于表示一个变量可以是多个类型之一,例如 Union[str, int]
表示变量可以是字符串
或整数
。
6. TypeVar:
用于定义泛型类型变量,可以用于泛型函数和类。
7. Callable:
用于表示函数或方法的类型,例如 Callable[[int, int], int]
表示接受两个整数参数并返回一个整数的函数。
三、如何导入 typing 模块
要使用 typing 模块中的类型注解,从 typing 模块
中导入所需的类型。
例如:
from typing import List, Dict, Tuple, Optional, Union
四、代码示例
1. 一个函数
chat(self,
prompt: Optional[str] = None,
messages: Optional[List[Dict]] = None,
stop: Optional[List[str]] = None,
stream: bool = False,
**kwargs) -> Union[str, Iterator[str]]:
2. 函数参数解释
1. prompt: Optional[str] = None:
含义
: 这是一个可选的字符串参数,表示用户提供的初始提示或消息。它可以用来启动对话或提供背景信息。
类型
: Optional[str]
表示该参数可以是一个字符串 (str)
或者 None
。
默认值
: 默认值为 None
,表示如果没有提供此参数,函数内部可能需要使用其他方式来处理或忽略这个提示。
2. messages: Optional[List[Dict]] = None:
含义
: 这是一个可选的列表参数,列表中的每个元素都是一个字典,表示一系列的消息历史记录。这些字典通常包含 role 和 content 键,用于标识消息的发送者和内容。
类型
: Optional[List[Dict]]
表示该参数可以是一个包含字典的列表 (List[Dict])
或者 None
。
默认值
: 默认值为 None,表示如果没有提供此参数,函数内部可能需要使用其他方式来处理或忽略消息历史。
3. stop: Optional[List[str]] = None:
含义
: 这是一个可选的列表参数,列表中的每个元素都是一个字符串,表示停止条件。这些条件可以用来控制生成的回复何时停止。
类型
: Optional[List[str]]
表示该参数可以是一个包含字符串的列表 (List[str])
或者 None
。
默认值
: 默认值为 None,表示如果没有提供此参数,函数内部可能需要使用其他方式来处理或忽略停止条件。
4. stream: bool = False:
含义
: 这是一个布尔参数,用于指定是否启用流式输出。如果设置为 True,则函数会逐步返回生成的内容;如果为 False,则会一次性返回完整的结果。
类型
: bool
默认值
: 默认值为 False
,表示默认情况下不启用流式输出。
5. **kwargs:
含义
: 这是一个关键字参数集合,允许你传递额外的参数到方法中。这些参数可能会被方法内部使用,或者传递给底层的聊天模型或服务。
类型
: 可变数量的关键字参数。
6. 返回值:
类型
: Union[str, Iterator[str]]
str
: 如果 stream
参数为 False,则返回一个字符串,表示完整的回复内容。
Iterator[str]`: 如果 stream 参数为 True,则返回一个迭代器,每次迭代返回生成的一部分内容。
五、简单的错误异常处理
from typing import Dict, Iterator, List, Optional, Union
def chat(
prompt: Optional[str] = None,
messages: Optional[List[Dict]] = None,
stop: Optional[List[str]] = None,
stream: bool = False,
**kwargs
) -> Union[str, Iterator[str]]:
"""
This function simulates a chat with an AI.
Parameters:
- prompt (Optional[str]): The initial prompt or message to start the conversation.
- messages (Optional[List[Dict]]): A list of dictionaries representing the message history.
- stop (Optional[List[str]]): A list of strings that can be used to stop the generation.
- stream (bool): If True, return the response as a stream of strings.
- **kwargs: Additional keyword arguments.
Returns:
- str: Full response if stream is False.
- Iterator[str]: Streamed response if stream is True.
"""
try:
# 检查是否有必要的参数
if not prompt and not messages:
raise ValueError("Either 'prompt' or 'messages' must be provided.")
# 构建消息历史
message_history = messages if messages else []
if prompt:
message_history.append({"role": "user", "content": prompt})
# 模拟后端服务调用
if stream:
# 如果启用流式输出,则模拟一个简单的流式响应
return iter(["S", "t", "a", "r", "t", "i", "n", "g", " ", "t", "h", "e", " ", "s", "t", "r", "e", "a", "m", "..."])
else:
# 如果不启用流式输出,则返回一个完整的字符串
return "This is a full response."
except ValueError as ve:
# 处理 ValueError 异常
print(f"ValueError: {ve}")
return None
except Exception as e:
# 处理其他异常
print(f"An unexpected error occurred: {e}")
return None
# 示例调用
response = chat(prompt="Hello, how are you?", stream=True)
if isinstance(response, Iterator):
for chunk in response:
print(chunk, end='')
elif response is None:
print("No response due to an error.")
else:
print(response)
1. 代码解释
try 语句
:
包含可能引发异常的代码块。如果代码块中发生异常,控制将转移到相应的 except 块。except ValueError as ve
:
处理ValueError
异常。as ve
允许你访问异常对象本身。
2. 错误处理:
- 在
except
块中, 可以打印错误消息
,记录错误,或者采取其他适当的措施。 - 如果发生异常,函数返回 None,表示没有有效响应。
3. 调用示例:
- 在调用函数后, 检查返回值的类型。
- 如果
返回值是 Iterator
,则正常处理流式输出。 - 如果
返回值是 None
,则表示发生了错误,并打印相应的消息。 - 如果
返回值是字符串
,则直接打印该字符串。
3. 注意事项
- 异常处理顺序:
如果有多个 except 块
,Python 会按照它们出现的顺序来匹配
异常。更具体的异常应该放在前面,更通用的异常(如 Exception)
放在后面
。 - 异常处理的最佳实践:
尽量具体地捕获异常,避免使用
过于宽泛的异常类型,如 Exception。在 except 块中处理错误,而不是仅仅打印错误信息
。例如,可以记录错误、重试操作、返回默认值等。