当前位置: 首页 > news >正文

Python学习:函数的使用

函数是 Python 编程的核心构建块,掌握函数的参数类型和嵌套用法,能让代码更简洁、灵活且可复用。本文将系统讲解 Python 函数的五大核心知识点 —— 必备参数、缺省参数、可变参数、关键字参数以及函数嵌套

一、函数参数基础:为什么参数很重要?​

函数的参数是实现 “输入 - 处理 - 输出” 逻辑的关键,它让函数摆脱固定值的束缚,能够根据不同输入产生不同结果。例如计算圆面积的函数,通过参数radius接收半径值,实现对任意圆的面积计算:

def circle_area(radius):​return 3.14 * radius **2​
​
print(circle_area(5))  # 输出:78.5​
print(circle_area(10)) # 输出:314.0

二、必备参数:函数调用的 “硬性要求”​

必备参数(Positional Arguments) 是指必须按顺序传递、且数量与函数定义完全匹配的参数,缺一不可。这是最基础也最常用的参数类型。​

特点:​

  • 必须在函数调用时显式传递​

  • 顺序必须与函数定义一致​

  • 数量必须与函数定义的参数数量相同

#必备参数 (位置参数) 传递和接收参数的顺序,个数要一致
def function_name(name,age,gender):print("Hello " + name + ", you are " + str(age) + " years old" + ", your gender is " + gender)
function_name("zhangsan",25,"male")结果:
Hello zhangsan, you are 25 years old, your gender is male

 三、缺省参数:带默认值的 “弹性选项”

缺省参数(Default Arguments) 是指在函数定义时指定默认值的参数,调用时可传可不传 —— 若不传,则使用默认值;若传,则覆盖默认值。​

特点:​

  • 定义时用参数名=默认值格式声明​

  • 必须放在必备参数之后(否则语法报错)​

  • 默认值只在函数定义时初始化一次(注意 mutable 对象的坑)​

实例 1:基础用法

def course_info(name, teacher="张教授"):​print(f"课程:{name},授课教师:{teacher}")​
​
# 不传缺省参数,使用默认值​
course_info("Python编程")  # 输出:课程:Python编程,授课教师:张教授​
​
# 传递缺省参数,覆盖默认值​
course_info("数据结构", "李教授")  # 输出:课程:数据结构,授课教师:李教授

实例 2:缺省参数的位置限制

# 错误:缺省参数不能放在必备参数前面​
def wrong_func(a=1, b):  # 报错:SyntaxError: non-default argument follows default argument​pass​
​
# 正确:缺省参数放在最后​
def right_func(b, a=1):​print(a + b)

实例 3:默认值为 mutable 对象的陷阱​

def add_item(item, lst=[]):  # 危险:默认值是可变列表lst.append(item)return lstprint(add_item(1))  # 输出:[1]
print(add_item(2))  # 输出:[1, 2](预期是[2],因默认列表被复用)# 正确写法:默认值设为None,在函数内初始化
def add_item_fixed(item, lst=None):if lst is None:lst = []lst.append(item)return lstprint(add_item_fixed(1))  # 输出:[1]
print(add_item_fixed(2))  # 输出:[2](符合预期)

四、可变参数:应对不确定数量的输入​

当函数需要接收不确定数量的参数时,可变参数(Variable Arguments)就能派上用场。Python 支持两种可变参数:*args和**kwargs。​

4.1 *args:接收任意数量的位置参数​

*args 用于收集未命名的位置参数,将其打包成一个元组(tuple)。​

特点:​

  • 定义时用*args表示(args 是约定俗成的名称,可改为其他名字,如*params)​

  • 接收所有未匹配的位置参数,类型为元组​

  • 必须放在必备参数和缺省参数之后​

def sum_numbers(*args):print(f"接收的参数:{args}(类型:{type(args)})")return sum(args)print(sum_numbers(1, 2, 3))  # 输出:接收的参数:(1, 2, 3)(类型:<class 'tuple'>);6
print(sum_numbers(10, 20, 30, 40))  # 输出:100
print(sum_numbers())  # 输出:0(空元组sum为0)

结合必备参数使用:​

def print_info(title, *args):​print(f"标题:{title}")​print(f"内容:{args}")​
​
print_info("兴趣爱好", "读书", "跑步", "编程")​
# 输出:​
# 标题:兴趣爱好​
# 内容:('读书', '跑步', '编程')

4.2 **kwargs:接收任意数量的关键字参数 

**kwargs 用于收集命名的关键字参数,将其打包成一个字典(dict)。​

特点:​

  • 定义时用**kwargs表示(kwargs 是约定俗成的名称,可改为** params)​

  • 接收所有未匹配的关键字参数,类型为字典(key 是参数名,value 是参数值)​

  • 必须放在参数列表的最后(所有参数之后)​

def user_profile(**kwargs):print(f"接收的参数:{kwargs}(类型:{type(kwargs)})")for key, value in kwargs.items():print(f"{key}:{value}")user_profile(name="张三", age=20, city="北京")
# 输出:
# 接收的参数:{'name': '张三', 'age': 20, 'city': '北京'}(类型:<class 'dict'>)
# name:张三
# age:20
# city:北京

结合其他参数使用:

def order(goods, *args, **kwargs):print(f"商品:{goods}")print(f"附加服务:{args}")print(f"订单信息:{kwargs}")order("手机", "贴膜", "碎屏险", price=5999, pay_method="支付宝")
# 输出:
# 商品:手机
# 附加服务:('贴膜', '碎屏险')
# 订单信息:{'price': 5999, 'pay_method': '支付宝'}

4.3 参数解包:传递列表 / 字典给可变参数​

当已有列表或字典,想将其元素作为可变参数传递时,可使用解包语法:​

  • 列表 / 元组前加*,解包为位置参数​

  • 字典前加**,解包为关键字参数

# 解包列表给*args
nums = [1, 2, 3, 4]
print(sum_numbers(*nums))  # 等价于sum_numbers(1, 2, 3, 4),输出:10# 解包字典给**kwargs
user_info = {"name": "李四", "age": 22, "city": "上海"}
user_profile(** user_info)  # 等价于user_profile(name="李四", age=22, city="上海")

五、关键字参数:强制按名称传递的参数​

关键字参数(Keyword-Only Arguments) 是指必须通过参数名传递的参数,不能按位置传递。定义时在参数前加*(或*args),*之后的参数即为关键字参数。​

特点:​

  • 必须显式通过参数名传递(如func(key=value))​

  • 放在*args之后、**kwargs之前(如果存在)​

  • 避免因参数顺序导致的调用错误

# 用*分隔,*之后的参数必须为关键字参数
def calc(a, b, *, operator):if operator == "+":return a + belif operator == "-":return a - belse:return "未知操作符"# 正确调用:operator必须按关键字传递
print(calc(10, 5, operator="+"))  # 输出:15# 错误调用:operator按位置传递
print(calc(10, 5, "+"))  # 报错:TypeError: calc() takes 2 positional arguments but 3 were given

结合*args使用:​

def print_details(*args, prefix, suffix):print(f"前缀:{prefix}")print(f"内容:{args}")print(f"后缀:{suffix}")print_details("a", "b", "c", prefix="start", suffix="end")
# 输出:
# 前缀:start
# 内容:('a', 'b', 'c')
# 后缀:end

六、函数嵌套:函数内部的 “函数工厂”​

Python 允许在函数内部定义另一个函数,称为函数嵌套(Nested Functions)。内部函数可以访问外部函数的变量,形成闭包(Closure),增强代码封装性和灵活性。

6.1 基础用法:内部函数的定义与调用 

def outer_func():print("这是外部函数")# 内部函数def inner_func():print("这是内部函数")# 外部函数中调用内部函数inner_func()outer_func()
# 输出:
# 这是外部函数
# 这是内部函数# 错误:内部函数不能在外部函数外直接调用
inner_func()  # 报错:NameError: name 'inner_func' is not defined

6.2 闭包:内部函数访问外部变量​

内部函数可以访问外部函数的局部变量,若内部函数引用了外部函数的变量且外部函数返回内部函数,则形成闭包。

def make_greeter(prefix):# 外部函数变量message = f"{prefix},欢迎!"# 内部函数引用外部变量messagedef greeter(name):return f"{message} 我是{name}"# 返回内部函数(不执行)return greeter# 创建两个不同的greeter函数
morning_greeter = make_greeter("早上好")
evening_greeter = make_greeter("晚上好")print(morning_greeter("张三"))  # 输出:早上好,欢迎! 我是张三
print(evening_greeter("李四"))  # 输出:晚上好,欢迎! 我是李四

闭包的价值在于保存外部函数的状态,如上面的prefix变量在make_greeter调用后仍被内部函数greeter引用。

6.3 嵌套函数的应用场景​

1.** 代码封装 :将辅助逻辑放在内部函数,避免外部命名污染。​

2. 闭包与装饰器 :装饰器(Decorator)的实现依赖函数嵌套(后续文章详解)。​

3. 动态生成函数 **:根据外部参数动态定义内部函数的行为(如上面的make_greeter)。

七、参数定义的顺序总结​

Python 函数参数的定义顺序必须严格遵守,否则会报语法错误,正确顺序为:​

  1. 必备参数(positional arguments)​

  2. 缺省参数(default arguments)​

  3. 可变位置参数(*args)​

  4. 关键字参数(keyword-only arguments)​

  5. 可变关键字参数(**kwargs)

def func(a, b=10, *args, c, d=20, **kwargs):print(f"必备参数:a={a}, b={b}")print(f"可变位置参数:args={args}")print(f"关键字参数:c={c}, d={d}")print(f"可变关键字参数:kwargs={kwargs}")func(1, 2, 3, 4, c=5, e=6, f=7)
# 输出:
# 必备参数:a=1, b=2
# 可变位置参数:args=(3, 4)
# 关键字参数:c=5, d=20
# 可变关键字参数:kwargs={'e': 6, 'f': 7}

八、实战案例:综合运用多种参数类型​

下面通过一个 “学生成绩管理” 函数,综合展示各种参数的用法:​

def manage_scores(name, *scores, exam_type="期中", pass_line=60, **kwargs):"""管理学生成绩的函数:param name: 学生姓名(必备参数):param scores: 多门成绩(可变位置参数):param exam_type: 考试类型(缺省参数):param pass_line: 及格线(关键字参数,强制按名称传递):param kwargs: 额外信息(可变关键字参数):return: 成绩总结"""total = sum(scores)avg = total / len(scores) if scores else 0passed = [s for s in scores if s >= pass_line]summary = (f"学生:{name}\n"f"考试类型:{exam_type}\n"f"成绩列表:{scores}\n"f"总分:{total},平均分:{avg:.1f}\n"f"及格科目:{len(passed)}/{len(scores)}\n"f"额外信息:{kwargs}")return summary# 调用函数
result = manage_scores("张三", 85, 90, 75, 60,  # name和scores(位置参数)exam_type="期末",        # 缺省参数pass_line=60,           # 关键字参数teacher="王老师", comment="进步明显"  # 可变关键字参数
)
print(result)

 结果:

学生:张三​
考试类型:期末​
成绩列表:(85, 90, 75, 60)​
总分:310,平均分:77.5​
及格科目:4/4​
额外信息:{'teacher': '王老师', 'comment': '进步明显'}

九、总结 

参数类型定义方式作用位置要求
必备参数a,b必须传递的基础参数最前面
缺省参数a=1,b=2带默认值,可省略传递必备参数之后
可变参数*args接收任意数量位置参数(元组)缺省参数之后
关键字参数*, c, d=3强制按名称传递可变参数之后
可变关键字参数**kwargs接收任意数量关键字参数(字典)最后面

http://www.lryc.cn/news/596807.html

相关文章:

  • webrtc整体架构
  • LeetCode热题100--205
  • Visual Studio中部署PaddleOCRv5 (借助ncnn框架)
  • Flink 状态管理设计详解:StateBackend、State、RocksDB和Namespace
  • 【笔记】Handy Multi-Agent Tutorial 第三章: CAMEL框架简介及实践(实践部分)
  • Redis原理之分布式锁
  • PowerShell自动化核对AD与HR系统账户信息实战指南
  • IDEA202403 超好用设置【持续更新】
  • ZooKeeper在Hadoop中的协同应用:从NameNode选主到分布式锁实现
  • 天津大学陈亚楠教授团队 ACS AEM:焦耳热超快合成非平衡态能源材料——毫秒级制备与跨体系性能突破
  • 昨天去看了电科金仓的发布会,有点东西!
  • 从 Linux 将文件下载到 Windows 的几种实用方法
  • 【AI智能体】Dify 开发与集成MCP服务实战操作详解
  • 嵌入式学习之路
  • Python笔记之跨文件实例化、跨文件调用、导入库
  • 为什么本地ip记录成0.0.0.1
  • 基于Python flask的常用AI工具功能数据分析与可视化系统设计与实现,技术包括LSTM、SVM、朴素贝叶斯三种算法,echart可视化
  • 慢 SQL接口性能优化实战
  • Fast Frequency Estimation Algorithm by Least Squares Phase Unwrapping
  • USB4.0:开启高速数据传输的新时代
  • 当if else比较多时候应该怎么避免?
  • MCP与企业数据集成:ERP、CRM、数据仓库的统一接入
  • #Linux权限管理:从“Permission denied“到系统安全大师
  • uniapp自定义圆形勾选框和全选框
  • iOS 抓包工具有哪些?2025实用指南与场景推荐
  • 重磅发布:Oracle ADG 一键自动化搭建脚本
  • 离线快速处理PDF格式转化的方案
  • 揭秘ThreadLocal核心原理与应用
  • Linux文件系统理解1
  • NLP自然语言处理的一些疑点整理