Python函数进阶

Python函数进阶

2026年9月16日·#编程学习/python学习笔记Python/函数·3930 字 20 分钟
浏览量加载中...
AI 摘要- DeepSeek

Python变量作用域、参数详解(位置参数、关键字参数、默认参数、不定长参数)、函数作为参数、匿名函数

封面图
Python函数进阶 - 封面图

变量作用域#

变量的作用域指的是变量的作用范围(标识这个变量在哪里可以使用,在哪儿不可以使用)。

全局变量#

在函数之外定义的变量,称之为全局变量,在整个文件中(包括函数内)都可以使用(通常定义在文件的顶部)。

局部变量#

在函数内部定义的变量,称之为局部变量,只能在该函数内部使用,外部无法访问(函数执行完毕后,会自动销毁其内部局部变量)。

示例#

# 定义函数
num = 100 # 全局变量
def circle_area(r):
pi = 3.14
area = pi * r * r # 局部变量
return area
count = 0 # 全局变量
# 调用函数
c_area = circle_area(10)
print(c_area)

global关键字#

global 关键字用于明确的告诉Python解释器,在函数中要使用全局变量,使得可以在函数内部修改全局变量的值。

示例1:不使用global(无法修改全局变量)#

num1 = 1 # 全局变量
def fun1():
num1 = 100 # 局部变量,只是新建了一个同名的局部变量
print(num1)
fun1() # 100
print(num1) # 1(全局变量未被修改)

示例2:使用global(可以修改全局变量)#

num1 = 1 # 全局变量
def fun1():
global num1 # 告诉python解释器,函数中使用全局变量num1
num1 = 100 # 修改全局变量num1
print(num1)
fun1() # 100
print(num1) # 100(全局变量被修改)

注意事项#

  • 在基于 global 声明全局变量时,要先声明,再使用

变量作用域小结#

  1. 什么是局部变量,全局变量?

    • 在函数内部定义的变量就是局部变量,函数外声明的变量是全局变量
  2. global关键字的作用?

    • 在函数内部使用,声明接下来要使用的是全局变量,语法:global xxx
  3. 注意事项

    • 尽量避免在函数中使用全局变量,因为会使代码难以维护和调试
    • 考虑使用函数参数和返回值来传递数据,而不是依赖全局变量
    • global 主要用在程序的状态、配置和计数器等场景中

函数传参方式#

传参方式指的是,在调用函数时,传递实参的方式。

1. 位置参数#

调用函数时根据函数定义时的位置来传递参数。

# 定义函数
def reg_stu(name, age, gender, city):
print(f"注册成功,姓名:{name},年龄:{age},性别:{gender},城市:{city}")
return {"name": name, "age": age, "gender": gender, "city": city}
# 调用函数(顺序必须与定义一致)
stu = reg_stu("张三", 18, "男", "北京")
print(stu)

要求:调用函数时参数顺序与定义函数时参数顺序完全一致

2. 关键字参数#

调用函数时以函数定义时形参名称作为关键字,以 "键=值" 的形式来传递参数(不要求顺序)。

# 定义函数
def reg_stu(name, age, gender, city):
print(f"注册成功,姓名:{name},年龄:{age},性别:{gender},城市:{city}")
return {"name": name, "age": age, "gender": gender, "city": city}
# 调用函数(顺序可以不一致)
stu = reg_stu(name="张三", age=18, gender="男", city="北京")
print(stu)
stu2 = reg_stu(gender="男", name="王武", city="上海", age=22)
print(stu2)

3. 位置参数与关键字参数混用#

# 位置参数在前,关键字参数在后
stu = reg_stu("赵四", 28, gender="男", city="上海")
print(stu)

要求:如果位置参数与关键字参数混用,关键字参数必须在位置参数之后(关键字参数之间,没有顺序要求)


位置参数 vs 关键字参数#

对比项位置参数关键字参数
优点简洁可读性强、易维护和扩展
缺点可读性差、易出错、维护难代码繁琐
适用场景参数少(不超过3个),且顺序自然参数较多,或易混淆的场景
# 位置参数(简洁但可读性差)
s = calc(87, 68, 92, 85)
# 关键字参数(可读性强)
s = calc(math=87, chinese=68, english=92, computer=85)

黄金法则:半年后回头看你今天写的代码,能否一眼看出每个参数的含义,如果不能,就应该使用关键字参数。


传参方式小结#

  1. 位置参数

    • 调用函数时,传入的实参的顺序与定义函数时形参的顺序完全一致
  2. 关键字参数

    • 调用函数时,通过 "形参名=值" 的形式传递参数,顺序没有要求
    • 如果同时存在位置参数与关键字参数,位置参数在前,关键字参数在后
  3. 两种传参方式的适用场景

    • 一切以代码结构清晰明了(可读性)、便于维护(维护性)为目标
    • 如果参数比较少(不超过3个),可直接使用位置参数
    • 如果参数数量较多,建议使用关键字参数

默认参数#

默认参数也称为缺省参数,用于在定义函数时,为参数提供默认值,调用函数时,可以不传递有默认值的参数。

# 定义函数(city有默认值'北京')
def reg_stu(name, age, gender, city='北京'):
print(f"注册成功,姓名:{name},年龄:{age},性别:{gender},城市:{city}")
return {"name": name, "age": age, "gender": gender, "city": city}
# 调用函数(不传city,使用默认值)
stu = reg_stu("张三", 18, "男")
print(stu) # 城市:北京
# 调用函数(传city,覆盖默认值)
stu = reg_stu("赵四", 22, "男", "深圳")
print(stu) # 城市:深圳

注意事项#

  • 默认参数必须放在没有默认值的参数列表的后面,一个函数在定义时是可以设置多个默认参数的
  • 函数调用时,如果为默认参数传递了值,则会修改默认的参数值;如果没有传递该参数,则直接使用默认值

不定长参数#

当参数个数不确定时,可以使用不定长参数解决这类问题。

1. 位置传递(*args)#

传递的所有匹配的位置参数都会被 args 变量收集,这些参数会合并封装为一个元组(注意并不会封装关键字参数)。

# 定义函数
def calc_data(*args):
min_data = min(args)
max_data = max(args)
avg_data = sum(args) / len(args)
return min_data, max_data, round(avg_data, 1)
# 调用函数
data = calc_data(10, 20, 30, 40, 50, 60, 70, 80, 90, 100)
print(data) # (10, 100, 55.0)
data = calc_data(100, 200, 300, 400, 500)
print(data) # (100, 500, 300.0)

注意事项#

  • args 只是约定俗成的变量名,并不是关键字,这里可以使用任何合法的变量名(如 *data)

2. 关键字传递(**kwargs)#

参数是以 "键=值" 形式传递的关键字参数,这些 "键=值" 参数都会被 kwargs 接受,并合并封装为一个字典类型。

# 定义函数
def calc_data(*args, **kwargs):
min_data = min(args)
max_data = max(args)
avg_data = sum(args) / len(args)
if kwargs.get('round'):
avg_data = round(avg_data, kwargs.get('round'))
return min_data, max_data, avg_data
# 调用函数(带配置参数)
data = calc_data(100, 200, 300, 400, round=2, count=0)
print(data) # (100, 400, 250.0)
# 调用函数(不带配置参数)
data = calc_data(33, 11, 28, 91, 32, 75, 49)
print(data) # (11, 91, 45.6)

注意事项#

  • kwargs 只是约定俗成的变量名,并不是关键字,这里可以使用任何合法的变量名(如 **options)

不定长参数小结#

  1. 什么是不定长参数?

    • 参数个数不确定,此时就可以使用不定长参数解决这类问题
  2. 不定长参数的分类?

    • *args:不定长位置参数,函数调用时,通过位置参数传递多个参数封装到一个元组(tuple)中
    • **kwargs:不定长关键字参数,函数调用时,通过关键字参数传递多个参数封装到一个字典(dict)中
  3. args与kwargs的应用场景?*

    • *args 适用于处理数量不确定的数据(核心数据)
    • **kwargs 适用于处理数量不确定的选项(函数的配置参数,用来定制函数的行为)
# 核心数据:你要什么
点奶茶("珍珠奶茶")
# 选项:你要什么样的
点奶茶("珍珠奶茶", 甜度="少糖", 冰度="去冰", 加料=["布丁", "珍珠"], 大小="大杯")

函数作为参数#

普通参数:数字、布尔、字符串、列表、元组、集合、字典等。

特殊参数:函数。

def add(x, y):
return x + y
def subtract(x, y):
return x - y
def calc(x, y, oper):
return oper(x, y)
# 传递的是函数中封装的逻辑
result = calc(10, 20, add)
print(result) # 30
result = calc(10, 20, subtract)
print(result) # -10

匿名函数#

匿名函数指的是没有名称的函数,需要通过 lambda 表达式来声明函数,可以简化简单函数的编写(单行表达式)。

定义语法#

lambda 参数列表 : 函数体

示例对比#

# 命名函数
def out_line():
print('-------------------------')
def add(x, y):
return x + y
out_line()
print(add(10, 20))
# 匿名函数
out_line = lambda : print('-------------------------')
add = lambda x, y: x + y
out_line()
print(add(100, 200))

注意事项#

  • 函数逻辑比较简单(单行表达式)且只在一个地方使用时,可以考虑使用匿名函数,简化书写(通常作为高阶函数的参数使用)
  • 匿名函数中可以返回结果,也可以不返回结果。返回结果时,不需要写 return,表达式的运行结果就是要返回的结果

匿名函数小结#

  1. 匿名函数的定义方式

    lambda 参数列表 : 函数体
  2. 命名函数与匿名函数的选择?

    • 建议使用匿名函数的情况:函数逻辑简单,只在一个地方调用(常作为高阶函数的参数)
    • 建议使用命名函数的情况:函数逻辑复杂,需要多步操作,需要多个地方重复使用或需要加文档说明的场景

代码的可读性和可维护性比简洁性更重要


总结口诀#

  • 作用域:函数外定义全局用,函数内定义局部用
  • global:想改全局先声明,global放在函数中
  • 位置参数:按顺序传,简洁但要记清楚
  • 关键字参数:键值对传,顺序随意可读性强
  • 默认参数:给个默认值,不传就用它
  • 不定长参数:*args收元组,**kwargs收字典
  • 匿名函数:lambda一行写,简单场景用它

相关#

练习题#

一、知识回顾(读完直接做下面的实践题)#

  1. 作用域:函数外定义的是全局变量(整个文件都能用),函数内定义的是局部变量(只在该函数里能用,函数执行完就销毁)
  2. 想在函数里修改全局变量,要在函数内先声明 global 变量名(先声明,再使用)
  3. 位置参数:调用时实参顺序必须与形参顺序完全一致(参数少、顺序自然时用)
  4. 关键字参数:调用时写成 形参名=值,顺序随意、可读性好
  5. 两种混用时,位置参数必须在前、关键字参数在后(关键字参数之间没有顺序要求)
  6. 默认参数(缺省参数):定义时给参数一个默认值,如 def reg_stu(name, age, gender, city='北京'):;不传就用默认值,传了就覆盖;默认参数要放在没有默认值的参数后面
  7. 不定长位置参数 *args:把多传的位置参数收集成一个元组(args 只是约定名,可以叫别的)
  8. 不定长关键字参数 **kwargs:把多传的关键字参数收集成一个字典(常用来收配置项,如 round=2)
  9. 函数也是”值”:函数可以当参数传给另一个函数,传进去的是它封装的逻辑,如 calc(10, 20, add)
  10. 匿名函数 lambda 参数列表 : 函数体:没有名字、一行写完,适合逻辑简单且只在一处使用的场景;返回结果不用写 return,表达式的值就是结果

二、裸写题#

  • 2-1 三角形类型判断 定义一个函数 triangle_type(a, b, c),根据传入的三个边长判定三角形类型:

    • 等边三角形:三边相等
    • 等腰三角形:两边相等
    • 普通三角形:三边都不相等
    • 不能构成三角形:任意两边之和小于等于第三边

    批改(2026-09-28):⚠️ 判断逻辑正确,但只测了 triangle_type(3, 3, 999)(不能构成三角形)一种情况,等边/等腰/普通三种分支都没验证;建议按参考答案把 4 种情况各跑一遍。

    提示(先自己想,实在想不出再点开)

    一级 · 思路:先过一遍”能不能围成三角形”的关(任意两边之和都要大于第三边),能围成的再按”三边相等 / 有两边相等 / 都不等”往下分 二级 · 方法:外层 if a + b > c and a + c > b and b + c > a:,内层用 if a == b == c: / elif a == b or a == c or b == c: / else:,各分支 return 对应的字符串 三级 · 骨架:if a + b > ____ and a + c > b and b + c > a: / if a == b == ____: / elif a == b ____ a == c ____ b == c: / else: return "不能构成三角形"

    参考答案(做完再点开)
    # 2-1
    def triangle_type(a, b, c):
    if a + b > c and a + c > b and b + c > a:
    if a == b == c:
    return "等边三角形"
    elif a == b or a == c or b == c:
    return "等腰三角形"
    else:
    return "普通三角形"
    else:
    return "不能构成三角形"
    print(triangle_type(3, 4, 5)) # 普通三角形
    print(triangle_type(3, 3, 5)) # 等腰三角形
    print(triangle_type(8, 8, 8)) # 等边三角形
    print(triangle_type(3, 4, 7)) # 不能构成三角形
  • 2-2 成绩统计函数 定义一个函数 calc_stats(*scores),接收任意数量的成绩,返回最高分、最低分、平均分。

    批改(2026-09-28):✅ 正确(最高分 96、最低分 78、平均分 87.8,输出与预期一致)。代码与文件末尾注释答案高度相似(连那组测试数据都一样),建议重做一遍确认掌握。

    提示(先自己想,实在想不出再点开)

    一级 · 思路:参数个数不定,就把它收成一包整体处理:最高、最低、平均值各用现成函数算出来,一起返回 二级 · 方法:定义时用不定长位置参数 *scores(收集成元组);最高 max(scores)、最低 min(scores)、平均 sum(scores) / len(scores)(要保留一位小数可以再套 round(值, 1));return 最高, 最低, 平均 一次返回三个值 三级 · 骨架:def calc_stats(____scores): / return ____(scores), min(scores), round(sum(scores) / ____(scores), 1)

    参考答案(做完再点开)
    # 2-2
    def calc_stats(*scores):
    return max(scores), min(scores), round(sum(scores) / len(scores), 1)
    highest, lowest, avg = calc_stats(85, 92, 78, 96, 88)
    print(f"最高分: {highest}, 最低分: {lowest}, 平均分: {avg}")
  • 2-3 学生信息注册 定义一个函数 register(name, age, gender, city='北京'),使用默认参数,返回学生信息字典。

    批改(2026-09-28):✅ 正确(默认值 城市=北京、传参覆盖成 城市=上海 两组输出都对)。与文件末尾注释答案高度相似(注释和测试数据都一致),建议重做一遍确认掌握。

    提示(先自己想,实在想不出再点开)

    一级 · 思路:其中一个参数在定义时就给好默认值——调用时不传就是默认的,传了就按传的来 二级 · 方法:默认参数写在参数列表最后,如 city='北京';函数里把参数装进字典 return {"name": name, "age": age, "gender": gender, "city": city} 三级 · 骨架:def register(name, age, gender, ____='北京'): / return {"name": ____, "age": age, "gender": gender, "city": city}

    参考答案(做完再点开)
    # 2-3
    def register(name, age, gender, city='北京'):
    return {"name": name, "age": age, "gender": gender, "city": city}
    # 使用默认值
    stu1 = register("张三", 18, "男")
    print(stu1) # {'name': '张三', 'age': 18, 'gender': '男', 'city': '北京'}
    # 覆盖默认值
    stu2 = register("李四", 20, "女", "上海")
    print(stu2) # {'name': '李四', 'age': 20, 'gender': '女', 'city': '上海'}

评论区

[ 标签 ]
# AI37# AI 编程2# AI工具1# AI绘图1# AI辅助开发2# Ajax7# Apifox1# AstrBot3# Astro2# CC Switch1# CDN2# Claude Code1# claudecode2# ClaudeCode1# Cloudflare2# CloudFlare2# CloudFlare-ImgBed3# coc4# CSS10# DeepSeek6# deepseek2# DELETE1# Docker5# EdgeOne3# Gist1# git1# GitHub1# hexo-circle-of-friends1# HTML9# HTTP10# ImageManager1# Java23# java13# JavaScript11# JavaWeb113# JDBC7# JSON2# JUnit1# LangChain25# Linux4# Logback1# Maven17# Muse Spark1# Mybatis1# MyBatis18# MySQL45# MySql1# NapCat1# Node.js1# obsidian2# Obsidian5# OpenCode4# ORM1# PathVariable1# PicGo1# PyCharm1# Python70# RequestBody1# RequestMapping1# RESTful风格1# skills1# Slf4j1# SpringBoot37# SpringMVC5# SQL2# Streamlit5# Svelte2# TailwindCSS1# Telegram3# Tlias2# Vercel1# vscode2# Vue20# Waline3# Web3# WebDAV1# Web基础6# Web开发6# WinSCP1# YAML1# 三层架构1# 中二宣言1# 书籍1# 使用文档10# 写作1# 函数2# 刷步数1# 前端52# 动态1# 动漫1# 包1# 单词2# 博客8# 博客工作流1# 博客开发2# 参数接收1# 友链1# 反思2# 后端48# 图床6# 地图1# 备份2# 大模型1# 奇思妙想1# 存储1# 学习方法6# 学校1# 宝塔面板3# 宝宝10# 实战4# 对象1# 导航栏1# 工具2# 布局2# 开发1# 开发工具1# 开发规范1# 开心1# 异常处理1# 影视2# 微信1# 性能优化2# 总结1# 想法15# 感受1# 感悟11# 指南1# 提示词工程2# 插件5# 故障排除1# 效率工具2# 教程10# 数据分析9# 数据库27# 数据结构1# 文件操作2# 斩神1# 日常95# 日志框架1# 朋友圈1# 朱元璋1# 模块1# 模板1# 正则表达式2# 测试3# 游戏2# 爬虫7# 生活迁移1# 电影2# 电脑1# 碎碎念1# 视觉识别1# 类1# 类型注解1# 网络基础2# 网络教室1# 羊毛2# 脚本2# 脚本工具1# 自动化2# 蓝奏云1# 表单1# 订阅推荐2# 记录2# 评论系统1# 词根1# 词缀1# 说说1# 足迹1# 跑步2# 路径参数1# 转载2# 运动1# 部署11# 部落冲突1# 配置1# 随机图1# 面向对象5# 音乐3# 音标1# 项目实战11# 饮食1# 驼峰命名1# 高德地图1
[ 公告 ]

如果你喜欢,那么欢迎来到我的世界!

了解更多
[ 音乐 ]
封面

音乐

暂未播放

0:000:00
暂无歌词
找不到相关结果。
[ contents ]
[ 全部文章 ]