Python 函数参数使用形式完全指南
·
Python函数参数非常灵活,支持多种传参方式。掌握这些参数形式是写出优雅Python代码的关键。
目录
- 位置参数
- 默认参数
- 关键字参数
- 可变参数
- 仅关键字参数
- 参数组合使用
- 参数解包
- 类型提示与参数
- 实际应用场景
位置参数
基本用法
位置参数是最基本的参数形式,按顺序传递:
def greet(name, message):
"""简单的问候函数"""
return f"{message}, {name}!"
# 按位置传递参数
result = greet("Alice", "Hello")
print(result) # Hello, Alice!
# 参数顺序很重要
result = greet("Hello", "Alice") # 错误顺序
print(result) # Alice, Hello! (逻辑错误)
多个位置参数
def calculate_volume(length, width, height):
"""计算长方体体积"""
return length * width * height
# 必须按正确顺序传递
volume = calculate_volume(10, 5, 3)
print(volume) # 150
# 顺序错误会导致错误结果
wrong_volume = calculate_volume(3, 10, 5) # 3*10*5=150 (巧合相同)
默认参数
基本用法
为参数提供默认值,调用时可省略:
def greet(name, message="Hello"):
"""带默认值的问候函数"""
return f"{message}, {name}!"
# 使用默认参数
result1 = greet("Alice") # Hello, Alice!
result2 = greet("Bob", "Hi") # Hi, Bob!
# 多个默认参数
def create_user(name, age, role="user", active=True):
"""创建用户信息"""
return {
"name": name,
"age": age,
"role": role,
"active": active
}
user1 = create_user("Alice", 25) # 使用默认role和active
user2 = create_user("Bob", 30, "admin", False)
默认参数陷阱
重要:默认参数只计算一次,不要使用可变默认值:
# 错误示例:使用可变默认值
def add_item(item, items=[]):
items.append(item)
return items
print(add_item(1)) # [1]
print(add_item(2)) # [1, 2] - 意外!
# 正确做法:使用None作为默认值
def add_item_correct(item, items=None):
if items is None:
items = []
items.append(item)
return items
print(add_item_correct(1)) # [1]
print(add_item_correct(2)) # [2] - 正确!
关键字参数
基本用法
通过参数名指定值,顺序不重要:
def describe_person(name, age, city):
"""描述个人信息"""
return f"{name} is {age} years old and lives in {city}"
# 使用关键字参数
result = describe_person(name="Alice", age=25, city="Beijing")
print(result) # Alice is 25 years old and lives in Beijing
# 顺序可以任意
result = describe_person(city="Shanghai", name="Bob", age=30)
print(result) # Bob is 30 years old and lives in Shanghai
# 混合使用位置和关键字参数
result = describe_person("Charlie", age=35, city="Guangzhou")
关键字参数的优势
# 提高代码可读性
def connect_to_database(host, port, username, password, database, timeout=30):
"""连接数据库"""
# 实现代码...
return f"Connected to {database} on {host}:{port}"
# 使用关键字参数更清晰
connection = connect_to_database(
host="localhost",
port=5432,
username="admin",
password="secret",
database="mydb",
timeout=60
)
# 比位置参数更易读
# connect_to_database("localhost", 5432, "admin", "secret", "mydb", 60)
可变参数
*args - 可变位置参数
接收任意数量的位置参数:
def sum_numbers(*args):
"""计算任意数量数字的和"""
print(f"接收到的参数: {args}") # 元组形式
return sum(args)
# 使用示例
result1 = sum_numbers(1, 2, 3) # 6
result2 = sum_numbers(1, 2, 3, 4, 5) # 15
result3 = sum_numbers() # 0
# 与其他参数结合
def make_sentence(*words):
"""将单词组成句子"""
return " ".join(words).capitalize() + "."
sentence = make_sentence("hello", "world", "from", "python")
print(sentence) # Hello world from python.
**kwargs - 可变关键字参数
接收任意数量的关键字参数:
def print_info(**kwargs):
"""打印任意关键字参数"""
for key, value in kwargs.items():
print(f"{key}: {value}")
# 使用示例
print_info(name="Alice", age=25, city="Beijing")
# name: Alice
# age: 25
# city: Beijing
print_info(title="Python", version="3.9", author="Guido")
# title: Python
# version: 3.9
# author: Guido
# 空调用
print_info() # 无输出
实际应用
def create_html_tag(tag_name, **attributes):
"""创建HTML标签"""
attrs_str = " ".join(f'{k}="{v}"' for k, v in attributes.items())
return f"<{tag_name} {attrs_str}>"
# 使用可变关键字参数
div = create_html_tag("div", class_="container", id="main", style="color: red")
print(div) # <div class="container" id="main" style="color: red">
a = create_html_tag("a", href="https://python.org", target="_blank")
print(a) # <a href="https://python.org" target="_blank">
仅关键字参数
基本用法
强制使用关键字传递的参数:
def calculate_total(price, *, tax_rate=0.1, discount=0):
"""计算总价,tax_rate和discount必须使用关键字"""
total = price * (1 + tax_rate) * (1 - discount)
return total
# 正确使用
total1 = calculate_total(100, tax_rate=0.15, discount=0.1)
total2 = calculate_total(100, discount=0.2) # 使用默认tax_rate
# 错误使用
# total = calculate_total(100, 0.15, 0.1) # TypeError
实际应用场景
def send_email(to, subject, body, *, cc=None, bcc=None, reply_to=None):
"""发送邮件,cc、bcc、reply_to必须使用关键字"""
print(f"发送给: {to}")
print(f"主题: {subject}")
print(f"正文: {body}")
if cc:
print(f"抄送: {cc}")
if bcc:
print(f"密送: {bcc}")
if reply_to:
print(f"回复地址: {reply_to}")
# 强制使用关键字,提高代码可读性
send_email(
"alice@example.com",
"会议通知",
"请参加明天的会议",
cc=["bob@example.com", "charlie@example.com"],
reply_to="admin@example.com"
)
参数组合使用
正确的参数顺序
参数定义必须遵循特定顺序:
- 位置参数
- 默认参数 / 关键字参数
- *args
- 仅关键字参数
- **kwargs
def complex_function(a, b, c=10, *args, d=20, e, **kwargs):
"""
复杂的参数组合示例
a, b: 位置参数
c: 默认参数
*args: 可变位置参数
d: 仅关键字参数(有默认值)
e: 仅关键字参数(无默认值)
**kwargs: 可变关键字参数
"""
print(f"a={a}, b={b}, c={c}")
print(f"args={args}")
print(f"d={d}, e={e}")
print(f"kwargs={kwargs}")
# 调用示例
complex_function(1, 2, 3, 4, 5, e=30, f=40, g=50)
# a=1, b=2, c=3
# args=(4, 5)
# d=20, e=30
# kwargs={'f': 40, 'g': 50}
实际组合示例
def process_data(data, *filters, verbose=False, **options):
"""
处理数据函数
data: 位置参数(必需)
*filters: 可变过滤条件
verbose: 仅关键字参数
**options: 其他选项
"""
print(f"处理数据: {data}")
if filters:
print(f"应用过滤器: {filters}")
if verbose:
print("详细模式开启")
if options:
print(f"其他选项: {options}")
# 调用示例
process_data([1, 2, 3], "filter1", "filter2", verbose=True, timeout=30, retry=3)
参数解包
* 解包位置参数
def print_coordinates(x, y, z):
"""打印坐标"""
print(f"坐标: ({x}, {y}, {z})")
# 使用解包
coordinates = (10, 20, 30)
print_coordinates(*coordinates) # 相当于 print_coordinates(10, 20, 30)
# 列表解包
points = [1, 2, 3]
print_coordinates(*points) # 坐标: (1, 2, 3)
# 部分解包
first, *rest = [1, 2, 3, 4, 5]
print(f"第一个: {first}, 其他: {rest}") # 第一个: 1, 其他: [2, 3, 4, 5]
** 解包关键字参数
def create_person(name, age, city, occupation):
"""创建人员信息"""
return {
"name": name,
"age": age,
"city": city,
"occupation": occupation
}
# 使用字典解包
person_data = {
"name": "Alice",
"age": 25,
"city": "Beijing",
"occupation": "Engineer"
}
person = create_person(**person_data)
print(person)
# {'name': 'Alice', 'age': 25, 'city': 'Beijing', 'occupation': 'Engineer'}
# 混合解包
def complex_func(a, b, c, d, e):
print(a, b, c, d, e)
args = [1, 2]
kwargs = {'d': 4, 'e': 5}
complex_func(*args, 3, **kwargs) # 1 2 3 4 5
类型提示与参数
基本类型提示
from typing import List, Dict, Optional, Union
def process_user(
name: str,
age: int,
hobbies: List[str],
metadata: Optional[Dict[str, str]] = None,
score: Union[int, float] = 0
) -> Dict[str, Union[str, int, List[str]]]:
"""
处理用户信息
"""
if metadata is None:
metadata = {}
return {
"name": name,
"age": age,
"hobbies": hobbies,
"metadata": metadata,
"score": score
}
# 使用示例
user = process_user(
name="Alice",
age=25,
hobbies=["reading", "coding"],
metadata={"department": "IT"},
score=95.5
)
更复杂的类型提示
from typing import Callable, Tuple
def data_pipeline(
data: List[int],
*processors: Callable[[List[int]], List[int]],
verbose: bool = False,
**options: str
) -> Tuple[List[int], Dict[str, str]]:
"""
数据处理管道
"""
result = data.copy()
for processor in processors:
result = processor(result)
if verbose:
print(f"处理后: {result}")
return result, options
# 使用示例
def double_numbers(nums):
return [x * 2 for x in nums]
def filter_even(nums):
return [x for x in nums if x % 2 == 0]
result, opts = data_pipeline(
[1, 2, 3, 4, 5],
double_numbers,
filter_even,
verbose=True,
source="test",
version="1.0"
)
实际应用场景
配置处理函数
def initialize_app(
host: str,
port: int,
*,
debug: bool = False,
reload: bool = False,
workers: int = 1,
**extra_settings
):
"""应用初始化配置"""
config = {
"host": host,
"port": port,
"debug": debug,
"reload": reload,
"workers": workers,
**extra_settings
}
print("应用配置:")
for key, value in config.items():
print(f" {key}: {value}")
return config
# 清晰的配置设置
app_config = initialize_app(
"0.0.0.0",
8000,
debug=True,
reload=True,
database_url="postgresql://localhost/mydb",
cache_enabled=True
)
数据验证函数
def validate_user_input(
username: str,
password: str,
*,
min_length: int = 6,
require_special_chars: bool = True,
require_numbers: bool = True,
**validation_rules
) -> bool:
"""验证用户输入"""
errors = []
if len(username) < min_length:
errors.append(f"用户名至少需要{min_length}个字符")
if len(password) < min_length:
errors.append(f"密码至少需要{min_length}个字符")
if require_special_chars and not any(c in "!@#$%^&*" for c in password):
errors.append("密码必须包含特殊字符")
if require_numbers and not any(c.isdigit() for c in password):
errors.append("密码必须包含数字")
# 处理额外的验证规则
for rule_name, rule_func in validation_rules.items():
if not rule_func(username, password):
errors.append(f"验证失败: {rule_name}")
if errors:
print("验证错误:")
for error in errors:
print(f" - {error}")
return False
return True
# 使用示例
is_valid = validate_user_input(
"alice",
"password123!",
min_length=8,
custom_rule=lambda u, p: "admin" not in u.lower()
)
灵活的API包装器
def api_call(
endpoint: str,
method: str = "GET",
*params: str,
headers: dict = None,
timeout: int = 30,
**payload
):
"""灵活的API调用函数"""
import requests
if headers is None:
headers = {}
url = f"https://api.example.com/{endpoint}"
# 构建查询参数
query_params = list(params)
# 处理不同的HTTP方法
if method.upper() == "GET":
response = requests.get(
url,
params=payload,
headers=headers,
timeout=timeout
)
elif method.upper() == "POST":
response = requests.post(
url,
json=payload,
headers=headers,
timeout=timeout
)
else:
raise ValueError(f"不支持的HTTP方法: {method}")
return response.json()
# 使用示例
# GET请求
user_data = api_call("users", "GET", id=123, fields="name,email")
# POST请求
result = api_call(
"users",
"POST",
headers={"Authorization": "Bearer token123"},
name="Alice",
email="alice@example.com",
age=25
)
总结
Python函数参数提供了极大的灵活性:
| 参数类型 | 语法 | 特点 | 适用场景 |
|---|---|---|---|
| 位置参数 | def func(a, b) |
按顺序传递 | 必需参数 |
| 默认参数 | def func(a=1) |
有默认值 | 可选参数 |
| 关键字参数 | func(a=1, b=2) |
按名称传递 | 提高可读性 |
| 可变位置参数 | def func(*args) |
任意数量位置参数 | 处理不定数量输入 |
| 可变关键字参数 | def func(**kwargs) |
任意数量关键字参数 | 处理配置选项 |
| 仅关键字参数 | def func(*, a) |
必须关键字传递 | 强制明确参数含义 |
更多推荐

所有评论(0)