挑战14天学会Python,第7天学习笔记!加油!
一、概述
在 Python 函数中,除了位置参数和关键字参数外,还存在两种强大的可变参数机制:
- 基于元组的可变参数(
args
):接收任意数量的位置参数,打包成元组。 - 基于字典的可变参数(
*kwargs
):接收任意数量的关键字参数,打包成字典。 此外,函数中变量的作用域决定了变量的可见性和生命周期。掌握这些内容,能编写更灵活、更安全的函数。
二、基于元组的可变参数(args
)
(一)定义
在形参前加 *
表示接收任意数量的位置参数,函数内部以元组形式访问。
(二)示例
def sum_all(*args):
"""计算所有传入数字的和"""
return sum(args)
result = sum_all(1, 2, 3, 4) # 传入4个位置参数
print(result) # 输出:10
(三)混合使用
def greet(name, *args):
print(f"Hello, {name}!")
for hobby in args:
print(f"- Likes {hobby}")
greet("Alice", "Python", "Reading", "Travel")
# 输出:
# Hello, Alice!
# - Likes Python
# - Likes Reading
# - Likes Travel
(四)注意事项
args
必须放在位置参数之后、关键字参数之前。- 在函数内部,
args
是一个元组,不可修改。
三、基于字典的可变参数(*kwargs
)
(一)定义
在形参前加 **
表示接收任意数量的关键字参数,函数内部以字典形式访问。
(二)示例
def create_profile(**kwargs):
"""创建用户档案"""
return kwargs
profile = create_profile(name="Bob", age=30, city="London")
print(profile) # 输出:{'name': 'Bob', 'age': 30, 'city': 'London'}
(三)混合使用
def display_info(title, **kwargs):
print(f"--- {title} ---")
for key, value in kwargs.items():
print(f"{key}: {value}")
display_info("User Profile", name="Charlie", email="charlie@example.com", active=True)
# 输出:
# --- User Profile ---
# name: Charlie
# email: charlie@example.com
# active: True
(四)注意事项
*kwargs
必须放在所有参数的最后。- 在函数内部,
kwargs
是一个字典,可修改键值对。
四、args
与 *kwargs
的组合使用
(一)完整示例
def universal_function(a, b, *args, **kwargs):
print(f"Required: {a}, {b}")
print(f"Optional args: {args}")
print(f"Optional kwargs: {kwargs}")
universal_function(1, 2, 3, 4, 5, name="Alice", city="New York")
# 输出:
# Required: 1, 2
# Optional args: (3, 4, 5)
# Optional kwargs: {'name': 'Alice', 'city': 'New York'}
(二)解包调用
调用函数时,可用 *
和 **
解包序列/字典作为参数:
nums = [10, 20, 30]
info = {"country": "USA", "zip": 10001}
universal_function(0, 0, *nums, **info)
# 输出:
# Required: 0, 0
# Optional args: (10, 20, 30)
# Optional kwargs: {'country': 'USA', 'zip': 10001}
五、函数中变量的作用域
(一)作用域分类
类型 | 描述 | 生命周期 |
---|---|---|
局部变量 | 在函数内部定义 | 函数调用期间 |
全局变量 | 在模块顶层定义 | 程序运行期间 |
内置变量 | Python 内置(如 len ) | 始终可用 |
(二)局部变量
def func():
x = 10 # 局部变量
print(x)
func() # 输出:10
# print(x) # 报错:NameError: name 'x' is not defined
(三)全局变量
y = 20 # 全局变量
def func():
print(y) # 访问全局变量
func() # 输出:20
(四)global
关键字
在函数内部修改全局变量,需使用 global
声明:
z = 30
def modify():
global z
z = 40 # 修改全局变量
modify()
print(z) # 输出:40
(五)nonlocal
关键字(嵌套函数)
避免使用全局变量(global
),减少模块级污染;让状态管理限定在函数作用域链内,更符合“最小权限原则”。显式声明 nonlocal
让维护者一目了然:此变量不属于当前函数,而是来自外层。在嵌套函数中修改外层函数的局部变量:
def outer():
x = 50
def inner():
nonlocal x
x = 60 # 修改外层函数的局部变量
inner()
print(x)
outer() # 输出:60
六、综合应用案例
(一)动态配置函数
def configure_system(*components, **settings):
print("Installing components:", components)
print("Applying settings:", settings)
configure_system("CPU", "GPU", "RAM", overclock=True, cooling="liquid")
# 输出:
# Installing components: ('CPU', 'GPU', 'RAM')
# Applying settings: {'overclock': True, 'cooling': 'liquid'}
(二)作用域隔离
count = 0 # 全局变量
def increment():
global count
count += 1
increment()
print(count) # 输出:1
七、注意事项与最佳实践
- 参数顺序:位置参数 →
args
→ 默认参数 →*kwargs
。 - 避免可变默认参数:使用
None
占位,函数内部初始化。 - 作用域最小化:优先使用局部变量,减少全局变量依赖。
- 文档字符串:为函数添加 docstring,说明参数用途。
八、总结
通过本笔记,我们掌握了:
- 使用
args
和*kwargs
处理可变数量参数。 - 函数作用域的分类及
global
/nonlocal
关键字的用法。 - 综合应用案例与最佳实践。
这些知识将帮助你编写更灵活、更安全的 Python 函数。后续我们将继续探讨高阶函数、闭包与装饰器等进阶主题。