Python 函数参数详解:从基础到高级用法
Python 函数参数详解:从基础到高级用法
一、函数定义基础
在 Python 中,函数使用 def
关键字定义,基本语法如下:
def function_name(parameters):"""函数文档字符串"""function_bodyreturn [expression]
1. 简单示例
def greet(name):"""向指定的人打招呼"""print(f"Hello, {name}!")greet("Alice") # 输出: Hello, Alice!
二、参数类型详解
1. 位置参数 (Positional Arguments)
最常见的参数类型,按位置顺序传递:
def describe_pet(animal_type, pet_name):print(f"I have a {animal_type} named {pet_name}.")describe_pet('hamster', 'Harry') # 正确顺序
describe_pet('Harry', 'hamster') # 错误顺序,逻辑不对
2. 关键字参数 (Keyword Arguments)
通过参数名指定值,顺序不重要:
describe_pet(pet_name='Harry', animal_type='hamster') # 明确指定参数名
3. 默认参数 (Default Arguments)
为参数提供默认值:
def describe_pet(pet_name, animal_type='dog'):print(f"I have a {animal_type} named {pet_name}.")describe_pet('Willie') # 使用默认的 animal_type='dog'
describe_pet('Harry', 'hamster') # 覆盖默认值
注意:默认参数必须放在非默认参数之后。
4. 可变位置参数 (*args)
接收任意数量的位置参数:
def make_pizza(*toppings):print("\nMaking a pizza with the following toppings:")for topping in toppings:print(f"- {topping}")make_pizza('pepperoni')
make_pizza('mushrooms', 'green peppers', 'extra cheese')
5. 可变关键字参数 (**kwargs)
接收任意数量的关键字参数:
def build_profile(first, last, **user_info):user_info['first_name'] = firstuser_info['last_name'] = lastreturn user_infouser_profile = build_profile('albert', 'einstein',location='princeton',field='physics')
print(user_profile)
三、参数传递的高级技巧
1. 解包参数列表
使用 *
解包序列作为位置参数:
args = [3, 6]
list(range(*args)) # 等同于 range(3, 6) → [3, 4, 5]
使用 **
解包字典作为关键字参数:
def parrot(voltage, state='a stiff', action='voom'):print(f"-- This parrot wouldn't {action}", end=' ')print(f"if you put {voltage} volts through it.", end=' ')print(f"E's {state}!")d = {"voltage": "four million", "state": "bleedin' demised", "action": "VOOM"}
parrot(**d)
2. 仅限关键字参数 (Python 3+)
在 *
后指定的参数必须使用关键字传递:
def concat(*args, sep="/"):return sep.join(args)concat("earth", "mars", "venus") # earth/mars/venus
concat("earth", "mars", "venus", sep=".") # earth.mars.venus
更明确的写法:
def write_multiple_items(file, *, separator=None):passwrite_multiple_items("file.txt", separator=",") # 正确
write_multiple_items("file.txt", ",") # 错误: separator必须用关键字指定
3. 类型提示 (Python 3.5+)
def greeting(name: str) -> str:return 'Hello ' + name
四、参数传递的常见模式
1. 参数组合顺序规则
- 位置参数
*args
可变位置参数- 关键字参数
**kwargs
可变关键字参数
正确示例:
def complex_function(a, b=2, *args, c=3, d=4, **kwargs):pass
2. 参数传递最佳实践
- 重要参数放在前面
- 相关参数可以组合成字典或对象传递
- 避免过多的参数(考虑使用类或分解函数)
- 为复杂函数添加类型提示
五、实际应用示例
1. 配置处理函数
def setup_connection(host, port=5432, *, timeout=30, retries=3):print(f"Connecting to {host}:{port}")print(f"Timeout: {timeout}s, Retries: {retries}")# 使用方式
setup_connection("db.example.com", timeout=60)
2. 数据转换管道
def process_data(data, *, normalize=True, filter=None, transform=None):if normalize:data = (data - data.mean()) / data.std()if filter:data = data[filter(data)]if transform:data = transform(data)return data
3. 装饰器中的参数传递
def retry(max_attempts=3, delay=1):def decorator(func):def wrapper(*args, **kwargs):attempts = 0while attempts < max_attempts:try:return func(*args, **kwargs)except Exception as e:attempts += 1if attempts == max_attempts:raisetime.sleep(delay)return wrapperreturn decorator@retry(max_attempts=5, delay=2)
def call_external_api():pass
六、常见问题与陷阱
- 可变对象作为默认参数:
def append_to(element, target=[]): # 错误!默认列表会在函数定义时创建target.append(element)return target# 正确做法
def append_to(element, target=None):if target is None:target = []target.append(element)return target
-
参数顺序混淆:确保位置参数在关键字参数之前
-
过度使用
*args
和**kwargs
:会使函数接口不清晰 -
忽略类型提示:在复杂项目中会导致维护困难
七、总结
Python 的函数参数系统非常灵活,提供了多种方式来定义和传递参数:
- 位置参数:最基础的参数传递方式
- 关键字参数:提高代码可读性
- 默认参数:简化函数调用
- 可变参数:处理不确定数量的输入
- 仅关键字参数:强制更清晰的API设计
掌握这些参数传递技术可以让你写出更灵活、更健壮的Python代码。根据不同的场景选择合适的参数传递方式,可以使你的函数接口既清晰又强大。