弹弹岛2vivo客户端
607.37MB · 2025-12-11
90% 的 Python 初学者分不清位置参数和关键字参数的区别。合格的程序员通过合理选择参数类型,让代码清晰易读。本文档帮你掌握这两种参数类型,写出专业代码。
Must(必做实践)
位置参数(Positional Arguments) 是 Python 函数调用时最基础、最常见的参数传递方式。简单来说,位置参数就是按照函数定义中参数的顺序,依次传递参数值。
想象一下你排队买电影票的场景:
位置参数就是这个道理:参数的值必须按照函数定义时的顺序传递,第一个值传给第一个参数,第二个值传给第二个参数,以此类推。
让我们通过一个简单的例子来理解位置参数:
# 定义一个问候函数
def greet(name, age):
"""
问候函数:显示姓名和年龄
参数:
name: 姓名(字符串)
age: 年龄(整数)
"""
print(f"你好,我叫 {name},今年 {age} 岁。")
# 使用位置参数调用函数
greet("小明", 20) # 第一个参数 "小明" 传给 name,第二个参数 20 传给 age
运行结果:
你好,我叫 小明,今年 20 岁。
关键点:
"小明" 是第一个参数,自动传给 name20 是第二个参数,自动传给 age位置参数有以下几个重要特点:
错误示例 1:参数顺序错误
def calculate_speed(distance, time):
"""
计算速度
参数:
distance: 距离(单位:公里)
time: 时间(单位:小时)
返回:
速度(单位:公里/小时)
"""
return distance / time
# 错误:参数顺序颠倒了,导致计算结果错误
speed1 = calculate_speed(2, 100) # 错误理解:distance=2, time=100,结果是 0.02 公里/小时
# 实际应该是:距离 100 公里,时间 2 小时,速度应该是 50 公里/小时
# 正确:按照函数定义的顺序传递参数
speed2 = calculate_speed(100, 2) # 正确:distance=100, time=2,结果是 50 公里/小时
注意:这个例子展示了参数顺序的重要性。如果顺序错误,计算结果会完全不同。calculate_speed(2, 100) 得到 0.02 公里/小时(错误),而 calculate_speed(100, 2) 得到 50 公里/小时(正确)。
错误示例 2:参数数量不匹配
def greet(name, age):
print(f"你好,我叫 {name},今年 {age} 岁。")
# 错误:参数数量不足
greet("小明") # TypeError: greet() missing 1 required positional argument: 'age'
# 错误:参数数量过多
greet("小明", 20, "北京") # TypeError: greet() takes 2 positional arguments but 3 were given
# 正确:参数数量匹配
greet("小明", 20)
位置参数最适合以下场景:
(x, y) 坐标、(长, 宽) 尺寸等 Python 官方文档 - 函数定义
Python 函数 - 菜鸟教程
Python 参数类型详解:位置参数与关键字参数 - 掘金
Python 函数参数详解 - 腾讯云开发者社区
Must(必做实践)
关键字参数(Keyword Arguments) 是 Python 中另一种重要的参数传递方式。与位置参数不同,关键字参数通过参数名来指定参数值,不需要关心参数的顺序。
想象一下你在餐厅点餐的场景:
不管你先说哪个,服务员都能准确记录下来。关键字参数就是这个道理:通过参数名明确指定每个参数的值,顺序可以任意调整。
让我们通过同样的例子来理解关键字参数:
# 使用同一个问候函数
def greet(name, age):
"""
问候函数:显示姓名和年龄
参数:
name: 姓名(字符串)
age: 年龄(整数)
"""
print(f"你好,我叫 {name},今年 {age} 岁。")
# 使用关键字参数调用函数
greet(name="小明", age=20) # 通过参数名明确指定值
# 顺序可以任意调整!
greet(age=20, name="小明") # 顺序颠倒,但结果完全相同
运行结果:
你好,我叫 小明,今年 20 岁。
你好,我叫 小明,今年 20 岁。
关键点:
参数名=值 的形式传递参数关键字参数有以下几个重要特点:
优势 1:提高代码可读性
# 函数定义:创建用户信息
def create_user(name, email, age, city, job):
"""
创建用户信息
参数:
name: 姓名
email: 邮箱
age: 年龄
city: 城市
job: 职业
"""
# ... 实现代码 ...
pass
# 位置参数:需要查看函数定义才能知道参数含义
create_user("张三", "[email protected]", 25, "北京", "工程师")
# 问题:只看调用代码,无法知道每个参数代表什么,必须查看函数定义
# 关键字参数:一眼就能看出每个参数的含义
create_user(
name="张三",
email="[email protected]",
age=25,
city="北京",
job="工程师"
)
# 优势:即使不看函数定义,也能清楚知道每个参数的含义
优势 2:避免参数顺序错误
def format_name(first_name, last_name):
"""
格式化姓名
参数:
first_name: 名
last_name: 姓
返回:
格式化后的姓名(格式:姓 名)
"""
return f"{last_name} {first_name}"
# 位置参数:容易搞混顺序,导致结果错误
# 如果用户想要"张三"这个名字(姓"张",名"三")
name1 = format_name("三", "张") # 正确:first_name="三", last_name="张",结果是 "张 三"(正确)
name2 = format_name("张", "三") # 错误:first_name="张", last_name="三",结果是 "三 张"(错误!应该是"张 三")
# 关键字参数:顺序明确,不会出错
name1 = format_name(first_name="三", last_name="张") # 明确:first_name="三", last_name="张",结果是 "张 三"
name2 = format_name(last_name="张", first_name="三") # 顺序颠倒,但结果正确:仍然是 "张 三"
注意:这个例子展示了关键字参数的优势。使用位置参数时,如果搞混了顺序(把"张"和"三"的位置颠倒),结果会是"三 张"(错误)。而使用关键字参数,即使顺序颠倒,Python 也能根据参数名正确匹配,结果始终是"张 三"(正确)。
优势 3:适合参数较多的函数
# 函数定义:参数较多(6 个参数)
def create_report(title, author, date, format, template, output_path):
"""
创建报告
参数:
title: 报告标题
author: 作者
date: 日期
format: 格式(如 "PDF"、"HTML" 等)
template: 模板名称
output_path: 输出路径
"""
# ... 实现代码 ...
pass
# 位置参数:容易出错,难以维护
create_report("月度报告", "张三", "2025-11-06", "PDF", "template1", "/reports/monthly.pdf")
# 问题:6 个参数排成一长串,难以区分哪个参数对应哪个值,容易搞混顺序
# 关键字参数:清晰明了,易于维护
create_report(
title="月度报告",
author="张三",
date="2025-11-06",
format="PDF",
template="template1",
output_path="/reports/monthly.pdf"
)
# 优势:每个参数的含义一目了然,即使参数很多也不会搞混
关键字参数最适合以下场景:
(width, height) 和 (height, width) 容易搞混 Python 官方文档 - 关键字参数
Python 函数 - 菜鸟教程
Python 参数类型详解:位置参数与关键字参数 - 掘金
PEP 3102 – 仅限关键字的参数
Python 函数参数详解 - 腾讯云开发者社区
Could(可以实践)
| 特性 | 位置参数(Positional Arguments) | 关键字参数(Keyword Arguments) |
|---|---|---|
| 传递方式 | 按照参数定义的顺序传递 | 通过 参数名=值 的形式传递 |
| 顺序要求 | 必须严格按照顺序传递 | 可以任意调整顺序 |
| 可读性 | 参数较多时,可读性较差 | 参数名明确,可读性强 |
| 灵活性 | 顺序错误会导致结果错误 | 顺序灵活,不易出错 |
| 适用场景 | 参数少(2-3 个)、顺序清晰 | 参数多(3 个以上)、含义重要 |
| 维护成本 | 修改函数定义时,调用处需要同步修改 | 修改函数定义时,调用处影响较小 |
| 专业使用 | 简单场景使用 | 专业首选,企业级开发规范 |
让我们通过一个具体的例子来对比两种参数类型:
# 定义一个创建用户信息的函数
def create_user(name, email, age, city, job):
"""
创建用户信息
参数:
name: 姓名
email: 邮箱
age: 年龄
city: 城市
job: 职业
"""
print(f"用户信息:{name} ({email}),{age} 岁,居住在 {city},职业是 {job}。")
对比 1:基本调用
# 位置参数:需要记住参数顺序,容易出错
create_user("张三", "[email protected]", 25, "北京", "工程师")
# 关键字参数:清晰明了,一眼就能看出每个参数的含义
create_user(
name="张三",
email="[email protected]",
age=25,
city="北京",
job="工程师"
)
对比 2:参数顺序错误
# 位置参数:顺序错误,导致结果错误
create_user("[email protected]", "张三", "北京", 25, "工程师")
# 结果:用户信息:[email protected] (张三),北京 岁,居住在 25,职业是 工程师。
# 错误!参数顺序完全搞混了
# 关键字参数:顺序可以任意调整,结果正确
create_user(
email="[email protected]",
name="张三",
city="北京",
age=25,
job="工程师"
)
# 结果:用户信息:张三 ([email protected]),25 岁,居住在 北京,职业是 工程师。
# 正确!虽然顺序不同,但结果完全正确
对比 3:代码可维护性 - 参数顺序调整的场景
在实际开发中,当函数需要调整参数顺序或添加新参数时,位置参数和关键字参数的区别会更加明显:
# 原始函数定义
def send_notification(user_id, title, message, priority, channel):
"""
发送通知
参数:
user_id: 用户ID
title: 标题
message: 消息内容
priority: 优先级(1-5)
channel: 渠道(email/sms/push)
"""
# ... 实现代码 ...
pass
# 假设需要调整参数顺序:将 priority 和 channel 的位置互换
def send_notification(user_id, title, message, channel, priority):
# ... 实现代码 ...
pass
场景 1:使用位置参数的代码
# 位置参数:参数顺序调整后,所有调用处都必须修改
# 旧代码:
send_notification(12345, "系统通知", "您的订单已发货", 3, "sms")
# ↑user_id ↑title ↑message ↑priority ↑channel
# 新函数定义要求:send_notification(user_id, title, message, channel, priority)
# 必须修改所有调用处,调整参数顺序:
send_notification(12345, "系统通知", "您的订单已发货", "sms", 3)
# ↑user_id ↑title ↑message ↑channel ↑priority
# 问题:必须记住新的参数顺序,容易出错,特别是参数很多时
场景 2:使用关键字参数的代码
# 关键字参数:参数顺序调整后,调用处无需修改
# 旧代码:
send_notification(
user_id=12345,
title="系统通知",
message="您的订单已发货",
priority=3,
channel="sms"
)
# 新函数定义:send_notification(user_id, title, message, channel, priority)
# 调用处无需任何修改,Python 会根据参数名自动匹配:
send_notification(
user_id=12345,
title="系统通知",
message="您的订单已发货",
priority=3, # 即使函数定义中 priority 在 channel 之后,也能正确匹配
channel="sms" # 即使函数定义中 channel 在 priority 之前,也能正确匹配
)
# 优势:参数顺序调整不影响调用代码,无需修改,维护成本低
场景 3:添加新参数(中间位置)
# 假设需要在中间位置添加新参数 category
def send_notification(user_id, title, category, message, priority, channel):
# ... 新参数 category 在 message 之前
pass
# 位置参数:必须修改所有调用处,在正确位置插入新参数
# 旧代码:send_notification(12345, "系统通知", "您的订单已发货", 3, "sms")
# 必须修改为:send_notification(12345, "系统通知", "订单", "您的订单已发货", 3, "sms")
# ↑user_id ↑title ↑category ↑message ↑priority ↑channel
# 问题:必须记住 category 的位置,容易插入错误位置
# 关键字参数:只需添加新参数,无需关心位置
send_notification(
user_id=12345,
title="系统通知",
category="订单", # 只需添加新参数,位置灵活
message="您的订单已发货",
priority=3,
channel="sms"
)
# 优势:参数插入位置灵活,不影响其他参数,代码清晰易读
总结:当函数参数需要调整顺序或添加新参数时,关键字参数的优势明显:
Must(必做实践)
在实际开发中,Python 允许我们同时使用位置参数和关键字参数,但必须遵循一个重要规则:位置参数必须在关键字参数之前。
def greet(name, age, city):
"""
问候函数
参数:
name: 姓名
age: 年龄
city: 城市
"""
print(f"你好,我是 {name},今年 {age} 岁,来自 {city}。")
# 正确:位置参数在前,关键字参数在后
greet("小明", age=20, city="北京")
# 错误:位置参数在关键字参数之后
greet(name="小明", 20, "北京") # SyntaxError: positional argument follows keyword argument
# 定义一个计算价格的函数
def calculate_price(quantity, unit_price, discount=0, tax_rate=0.1):
"""
计算商品总价
参数:
quantity: 数量(位置参数)
unit_price: 单价(位置参数)
discount: 折扣(关键字参数,有默认值)
tax_rate: 税率(关键字参数,有默认值)
"""
subtotal = quantity * unit_price
final_price = subtotal * (1 - discount) * (1 + tax_rate)
return final_price
# 混合使用:前两个参数用位置参数,后两个用关键字参数
price1 = calculate_price(10, 100, discount=0.1, tax_rate=0.08)
# 结果:10 * 100 * (1 - 0.1) * (1 + 0.08) = 972.0
# 也可以全部使用关键字参数
price2 = calculate_price(quantity=10, unit_price=100, discount=0.1, tax_rate=0.08)
# 使用默认值
price3 = calculate_price(10, 100) # discount=0, tax_rate=0.1,结果是 1100.0
混合使用位置参数和关键字参数可以兼顾两者的优势:
quantity、unit_price 等简单参数discount、tax_rate 等有默认值的参数 Python 官方文档 - 参数传递
Python 函数 - 菜鸟教程
Python 参数类型详解:位置参数与关键字参数 - 掘金
Python 函数参数详解 - 腾讯云开发者社区
⭐ Should(建议实践)
在实际开发中,如何选择位置参数和关键字参数?以下是合格程序员的最佳实践建议:
适合使用位置参数的情况:
参数数量少(2-3 个参数):顺序容易记忆
# 适合:只有 2 个参数,顺序清晰
def calculate_area(length, width):
"""
计算矩形面积
参数:
length: 长度
width: 宽度
返回:
面积
"""
return length * width
# 参数少且含义明确,使用位置参数简单直观
area = calculate_area(10, 5) # length=10, width=5,结果是 50
参数顺序有明确含义:如坐标 (x, y)、尺寸 (长, 宽) 等
# 适合:坐标顺序明确
def draw_point(x, y):
"""
绘制点
参数:
x: x 坐标
y: y 坐标
"""
# ... 绘制点 ...
pass
# 坐标顺序是约定俗成的(先 x 后 y),使用位置参数自然
draw_point(100, 200) # x=100, y=200,顺序清晰
简单函数调用:不需要特别强调参数含义
# 适合:简单函数
def greet(name, age):
"""
问候函数
参数:
name: 姓名
age: 年龄
"""
print(f"Hello, {name}, you are {age} years old.")
# 参数含义简单明了,使用位置参数简洁
greet("Alice", 25) # name="Alice", age=25,简洁明了
强烈建议使用关键字参数的情况:
参数数量多(3 个以上参数):提高可读性
# 强烈建议:参数较多(7 个参数),使用关键字参数
def create_user(name, email, age, city, job, phone, department):
"""
创建用户
参数:
name: 姓名
email: 邮箱
age: 年龄
city: 城市
job: 职业
phone: 电话
department: 部门
"""
# ... 创建用户 ...
pass
# 参数多时,使用关键字参数提高可读性和可维护性
create_user(
name="张三",
email="[email protected]",
age=25,
city="北京",
job="工程师",
phone="13800138000",
department="研发部"
) # 清晰明了,易于维护
参数含义重要:需要明确每个参数的作用
# 强烈建议:参数含义重要,使用关键字参数
def send_email(to, subject, body, cc=None, bcc=None, attachments=None):
"""
发送邮件
参数:
to: 收件人
subject: 主题
body: 正文
cc: 抄送(可选)
bcc: 密送(可选)
attachments: 附件(可选)
"""
# ... 发送邮件 ...
pass
# 参数含义重要,使用关键字参数让每个参数的作用一目了然
send_email(
to="[email protected]",
subject="重要通知",
body="这是一封重要邮件",
cc=["[email protected]"],
attachments=["report.pdf"]
) # 每个参数的含义一目了然
参数顺序容易混淆:如 (width, height) 和 (height, width)
# 强烈建议:避免顺序混淆
def create_window(width, height, title):
"""
创建窗口
参数:
width: 宽度
height: 高度
title: 标题
"""
# ... 创建窗口 ...
pass
# 容易混淆:width 和 height 的顺序容易搞混
create_window(800, 600, "窗口标题") # 难以确定是 width=800, height=600 还是相反
# 清晰明确:使用关键字参数避免混淆
create_window(width=800, height=600, title="窗口标题") # 明确:width=800, height=600
有默认值的参数:建议使用关键字参数
# 强烈建议:有默认值的参数使用关键字参数
def process_data(data, format="json", encoding="utf-8", compress=False):
"""
处理数据
参数:
data: 要处理的数据
format: 格式(默认:"json")
encoding: 编码(默认:"utf-8")
compress: 是否压缩(默认:False)
"""
# ... 处理数据 ...
pass
# 有默认值的参数使用关键字参数,明确指定需要修改的参数
process_data(
data=my_data,
format="csv", # 修改格式为 CSV
encoding="gbk", # 修改编码为 GBK
compress=True # 启用压缩
) # 明确指定需要修改的参数,其他参数使用默认值
根据合格程序员的实践经验,以下是选择参数类型的原则:
| 场景 | 推荐方式 | 原因 |
|---|---|---|
| 参数数量 ≤ 2 | 位置参数 | 简单直观 |
| 参数数量 ≥ 3 | 关键字参数 | 提高可读性 |
| 参数顺序清晰 | 位置参数 | 顺序明确 |
| 参数顺序易混淆 | 关键字参数 | 避免错误 |
| 有默认值 | 关键字参数 | 明确指定 |
| 团队协作 | 关键字参数 | 降低沟通成本 |
| 公共 API | 关键字参数 | 避免误用 |
Python 官方文档 - 函数定义
PEP 8 – Python 代码风格指南
Python 函数参数最佳实践 - 腾讯云开发者社区
Python 参数类型详解:位置参数与关键字参数 - 掘金
通过本文档的学习,你现在应该能够:
理解位置参数和关键字参数的区别
掌握两种参数类型的使用方法
了解最佳实践和选择原则
避免常见错误
记住这 3 个关键点:
Could(可以实践)
在掌握了位置参数和关键字参数之后,建议继续学习:
*args(位置可变参数)和 **kwargs(关键字可变参数),处理不确定数量的参数* 强制某些参数必须用关键字传递/ 强制某些参数必须用位置传递通过本文档的学习,你已经掌握了 Python 位置参数和关键字参数的核心知识。从 90% 初学者容易混淆的场景,到现在能够理解合格程序员的参数选择策略,你已经迈出了成为专业 Python 开发者的重要一步。
关键收获:
实践建议:
继续深入学习 Python 的其他参数类型,将这些知识应用到实际项目中,你的代码质量将不断提升。相信通过持续的学习和实践,你一定能写出像合格程序员一样专业、优雅的代码!
作者:郑恩赐
机构:厦门工学院人工智能创作坊
日期:2025 年 11 月 07 日