Skip to content

03 · 函数、模块与包管理 ​

🎯 难度:零基础⏱ 预计:60 分钟# 函数# import# uv

函数定义 ​

js
function greet(name, prefix = '你好') {
  return `${prefix},${name}`
}
greet('Lin', '欢迎')
python
def greet(name, prefix="你好"):
    """生成一句问候语。"""  # docstring,描述函数用途
    return f"{prefix},{name}"

print(greet("Lin"))
print(greet("Lin", prefix="欢迎"))  # 关键字参数

位置参数按顺序匹配;关键字参数按名称匹配。client.create(model="...", messages=...) 用的正是关键字参数。函数没有显式 return 时返回 None。

类型注解先认识一下 ​

python
def add(a: int, b: int) -> int:
    return a + b

: int 表示参数类型,-> int 表示返回类型。类似 TS 的 (a: number, b: number): number。它主要服务编辑器和静态检查器,并不是自动的运行时校验。

参数展开 ​

python
def log(*args, **kwargs):
    print(args)    # tuple:所有额外的位置参数
    print(kwargs)  # dict:所有额外的关键字参数

log("hello", "agent", level="info")

params = {"a": 2, "b": 3}
print(add(**params))  # 等价于 add(a=2, b=3)

* 展开序列,** 展开字典。Agent 将模型生成的参数 JSON 解析成 dict 后,经常用 function(**args) 调工具。

一个经典坑

不要用可变对象作为默认值:def append(item, items=[]):。默认 list 只创建一次,所有调用共享它。

正确写法:

python
def append(item, items=None):
    if items is None:
        items = []
    items.append(item)
    return items

函数也是值 ​

python
def double(x):
    return x * 2

handlers = {"double": double}
print(handlers["double"](3))  # 6

这就是后面「工具注册表」的基础:根据字符串工具名,从白名单里找到函数,而不是执行模型提供的任意代码。

模块:一个文件就是一个模块 ​

创建两个文件:

python
def add(a: int, b: int) -> int:
    return a + b
python
from math_tools import add

print(add(2, 3))

同目录下运行 uv run main.py,得到 5。

另一种写法是 import math_tools,然后 math_tools.add(2, 3)。模块路径不带 .py。不要把自己的文件命名为 openai.py、json.py、typing.py,会遮蔽同名库。

程序入口 ​

python
def main():
    print("程序开始")

if __name__ == "__main__":
    main()

直接运行这个文件时执行 main;被别的文件 import 时不执行。避免 import 模块就触发 API 计费或开始交互。

标准库 vs 第三方库 ​

  • json、os、pathlib、asyncio:Python 自带,不需要安装。
  • openai、pydantic、httpx:第三方,先 uv add。
bash
uv add httpx
uv run main.py
uv sync          # 别人克隆项目后恢复依赖

uv add 更新 pyproject.toml 和 uv.lock;这两个文件应提交,.venv 不提交。不要向系统 Python 全局安装项目依赖。

动手练习 ​

定义 celsius_to_fahrenheit(celsius),放在 temperature.py,再从 main.py 导入并调用。公式:摄氏度 × 9 ÷ 5 + 32。

参考答案
python
def celsius_to_fahrenheit(celsius: float) -> float:
    return celsius * 9 / 5 + 32
python
from temperature import celsius_to_fahrenheit
print(celsius_to_fahrenheit(22))  # 71.6

用心写给每一个想入门 Agent 开发的前端工程师