news 2026/5/20 4:07:13

一小时搞懂Python函数:原理+实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
一小时搞懂Python函数:原理+实践

目录

🙄什么是Python函数(了解函数的概念)

🤔为什么需要它?(背景和痛点)

😮函数的分类(函数有哪些?)

内置函数

标准库函数

第三方库函数

定义函数

🧐核心原理拆解(搞清楚他们是如何工作的?)

函数的定义

函数的调用

函数的参数

形参和实参的概念

位置参数

默认参数

关键字参数

不定长参数

函数的返回值

🤑案例实操

案例一:基础函数(无参+有参)

案例二:默认参数+可变参数

案例三:return 返回值

🤓关联知识(通过函数,了解变量的作用域)

什么是作用域?

全局变量和局部变量

案例——全局和局部变量

🤫 避坑总结

🥳三条学习心法

心法 1:参数 + return > global

心法 2:函数要"专一"

心法 3:默认参数用不可变对象


🙄什么是Python函数(了解函数的概念)

  • Python函数:是一个被命名的、独立的、完成特定功能的代码段,有时候给调用它的程序一个返回值。
  • 💡核心导读:Python函数就是一个个功能明确的小工具,当用到某个工具时直接调用。它不仅能帮我们把复杂的任务分解成简单的步骤,还能提高代码的复用性和可读性。

🤔为什么需要它?(背景和痛点)

  • 没有函数之前,我们可能会在代码中多次重复地编写相同的功能代码,这不仅浪费时间,还会使代码变得冗长且难以维护。
  • 函数带来的核心优势:
    • 提高代码复用性,减少重复代码;
    • 使代码逻辑更加清晰,便于理解和调试;
    • 模块化编程,方便团队协作开发,每个人负责不同的函数模块。

😮函数的分类(函数有哪些?)

内置函数

在编写代码过程中,可以拿来直接使用的时内置函数(如:print() / input() / min() / max() 等)

函数作用
print()输出内容
len()获取长度
type()查看类型
input()接收输入
sum()求和

标准库函数

通过import语句导入库,然后使用该库中定义的函数。

模块函数作用
mathsqrt()开平方
randomrandint()随机整数
timesleep()延时

第三方库函数

Python社区提供了很多高质量的库,通过下载安装这些库后,也可以使用import语句导入,然后使用这些第三方库的函数。

函数
numpyarray()
pandasread_excel()
requestsget()

定义函数

用户根据自己的需求自定义的函数,这也是我们需要学习的,根据需求构建合适的函数来实现某个功能。

🧐核心原理拆解(搞清楚他们是如何工作的?)

函数的定义

  • def 关键字开始,告诉Python我要定义一个函数。
  • 函数名是函数的标识,所以要遵循命名规则,通常全小写且单词之间使用下划线连接。
  • 参数是函数运行时需要的输入数据,可以是0个或者多个
  • 函数体是函数的核心部分,包含了具体的处理逻辑,需要注意的是这部分代码需要缩进,表明下面这部分代码属于该函数。
  • return 语句用于返回函数的处理结果,如果没有 return 语句,函数默认返回 None
def function_name([参数1,参数2,……]): ''' 文档字符串(可选,用于解释函数功能) ''' 函数体(注意必须缩进) …… return 返回值 # 可选,用于结束函数并返回结果,不写这条语句默认返回None

函数的调用

当我们需要使用函数的功能时,通过函数名加上圆括号来调用它,如果函数有参数,需要在圆括号内传入相应的实参

函数名([参数1,参数2,……])

函数的参数

主要参数类型:默认参数、关键字参数、位置参数、不定长参数

在了解上面那三种参数类型之前,首先需要认识什么是:形参实参?

形参和实参的概念

形参(形式参数):是函数定义时小括号中的参数,用来接收参数的,并在函数内部作为变量使用。

实参(实际参数):是函数调用时小括号中的参数,用来把数据传递到函数内部

# 形参 def two_numbers_sum(a, b): # 函数的定义,其中的a,b是形参 return a + b # 实参 result = two_numbers_sum(3, 4) # 函数的调用,其中的3, 4是实参

位置参数

按位置顺序传递,最为常见

示例:

def two_numbers_sum(a, b): # 当调用函数时,按照形参定义的位置顺序,一次传递参数 return a + b result = two_numbers_sum(3, 4) # 位置参数:实参“3”对应形参“a”,实参“4”对应形参“b”

默认参数

给参数设置默认值,调用时可以不传参数,如果传参,则会变成和传入参数一样的值。一般默认参数放到形参的最后面。

示例:

def user_info(user_name, age, gender='男'): # 格式化打印用户信息 print("用户名:{0}, 年龄:{1}, 性别:{2}".format(user_name, age, gender)) user_info("小王", 18) user_info("小刘", 20, "女") # 运行结果 # 用户名:小王, 年龄:18, 性别:男 # 用户名:小刘, 年龄:20, 性别:女

通过上面的示例可知:函数"user_info()"中有默认参数" gender ",其默认值是“男”。当没有传递该参数时,函数中形参“gender”的值就是“男”;如果传递了参数“女”,则函数中的“gender”的值就是“女”。

关键字参数

调用时指定参数名,此时就不需要按照位置参数的顺序进行传参了。

def user_info(user_name, age, gender='男'): # 格式化打印用户信息 print("用户名:{0}, 年龄:{1}, 性别:{2}".format(user_name, age, gender)) # 调用函数时,使用关键字参数指定传递的参数值,此时的参数就可以不按照定义函数时的顺序进行传递了 user_info(age=22, user_name="小张") # 运行结果 # 用户名:小张, 年龄:22, 性别:男

不定长参数

不定长参数:接收任意多个参数,包括” *args “ 和" **kwargs "两种。

参数类型说明示例
*args接收任意多个位置参数,变成元组def total(*nums)
**kwargs接收任意多个关键字参数,变成字典def info(**data)

不定长参数也是放到形参的最后面,如果同时又默认参数和不定长参数,最好的方式就是把不定长参数放到默认参数之后。

✅推荐正确顺序:

普通位置参数 -> 默认参数 -> 不定长参数(*args) -> 不定长参数(**kwargs)

# 按照标准顺序定义函数 def my_func(a, b=10, *args, **kwargs): print(f"普通参数 a: {a}") print(f"默认参数 b: {b}") print(f"不定长参数 args (元组): {args}") print(f"不定长关键字参数 kwargs (字典): {kwargs}") # 调用函数 my_func(1, 2, 3, 4, 5, name="小明", age=18) # 输出结果 # 普通参数 a: 1 # 默认参数 b: 2 # 不定长参数 args (元组): (3, 4, 5) # 不定长关键字参数 kwargs (字典): {'name': '小明', 'age': 18}

❓可能有人问:

为什么调用函数的时候使用了“关键字函数(name="小明", age=18)”为什么会变成字典呢?

因为这不是“关键字函数”,关键字函数确实是在函数调用的括号里定义的,定义方式:形参名=数据。可以看到上面在函数定义的形参列表中没有"name,age"这两个形参,但是有不定长参数“ **kwargs ”,所以这两个参数会被打包进“ **kwargs ”变成字典的形式。【至于他为什么会变成字典涉及到“拆包”的思想,这个在本章节不详细讲解,还请谅解】

函数的返回值

return后面可以跟一个值、多个值、或不写

跟多个值时,Python会自动打包成元组

函数遇到 return 会立即结束,后面的代码不在执行


🤑案例实操

案例一:基础函数(无参+有参)

# 无参函数:打招呼 def say_hello(): print("hello world") say_hello() # 调用无参函数 # 输出结果:hello world # 带参函数:求两数之和 def two_numbers(a, b): result = a + b return result print(two_numbers(3, 5)) # 调用带参函数并打印结果 # 输出结果:8

案例二:默认参数+可变参数

# 默认参数 def user_info(name, age, gender="男"): print(f"姓名:{name},年龄:{age},性别:{gender}") user_info("小明", 18) # 输出:姓名:小明,年龄:18,性别:男 # 可变参数 *args:计算任意多个数的总和 # 计算小明的所有考试成绩 def total_sum(name, age, gender="男", *numbers): result = 0 for num in numbers: result += num print(f"姓名:{name},年龄:{age},性别:{gender},总分:{result}") total_sum("小明", 18, 80, 90, 88) # 输出:姓名:小明,年龄:18,性别:80,总分:178

上述不定长参数“ *args ”接收的参数是,先按照位置参数的顺序将前面的实参接收,最后剩下的内容就是“ *args ”打包的内容。所以上述出现了“性别:80”的情况,所以当参数较多,使用“ *args ”接收参数时,实参尽量和形参的数量和顺序对应,更好的方式是使用关键字参数。

# 使用不定长参数**kwargs定义一个函数,接受任意数量的关键字参数,并打印出这些参数的键和值。 def user_info(name,age,gender='男',**info): print('姓名:%s'%name) print('年龄:%d'%age) print('性别:%s'%gender) print('其他信息:') for key,value in info.items(): print('%s:%s'%(key,value)) user_info('李四',age=25,job='程序员',city='上海',hobby='篮球') print('-'*20) user_info('张三',gender='女',job='学生',city='北京',age=20,hobby='唱歌') # 输出结果: # 姓名:李四 # 年龄:25 # 性别:男 # 其他信息: # job:程序员 # city:上海 # hobby:篮球 # -------------------- # 姓名:张三 # 年龄:20 # 性别:女 # 其他信息: # job:学生 # city:北京 # hobby:唱歌

由此可见,不定长参数“ **kwargs ”会接收任意数量的关键字参数。而当同时使用关键字参数和不定长参数时,不按照形参的位置顺序传参也没关系,函数接收参数是按照形参的顺序依次接受的,当到了“ gender ”参数的时候,会现在函数调用的实参中寻找“ gender ”参数,找到就接收,而其他“ key = value ”形式的参数就会被“ **kwargs ”接收。

案例三:return 返回值

无 return 语句

# 不加return 语句 def user_info(name, age): print(f"Name: {name}, Age: {age}") # 使用一个变量接收函数的返回值 ret = user_info("Tom", 18) print(ret) # 输出结果: # Name: Tom, Age: 18 # 此结果是函数中的print()打印的结果 # None # 此结果是打印函数的返回值

可见,不写 return 语句默认返回值为“ None ”。

使用 return 返回单个值

# 使用 return 语句返回单个值 def add(a, b): return a + b # 使用一个变量接收函数的返回值 ret = add(1, 2) print(ret) # 3

使用 return 语句返回多个值

# 使用 return 语句返回多个值 def calculate(a, b): sum_result = a + b difference = a - b return sum_result, difference # 调用函数并接收返回的多个值 result_sum, result_diff = calculate(10, 5) print("两数求和:", result_sum) # 输出: 两数求和: 15 print("两数作差:", result_diff) # 输出: 两数作差: 5 # 打印函数的返回值 print(calculate(10, 5)) # 输出: (15, 5)

可见,return 返回多个结果时,是以元组的形式返回的。而接收函数的返回值使用的是“拆包”的思想。

🤓关联知识(通过函数,了解变量的作用域)

变量根据作用域的不同分为:

  • 全局变量
  • 局部变量

什么是作用域?

作用域:实际上就是变量的“活动范围”。

Python 中变量的作用域遵循LEGB 规则(由内到外查找):

L → E → G → B 局部 → 嵌套 → 全局 → 内置
  • L(Local):函数内部定义的变量

  • E(Enclosing):嵌套函数的外层函数变量

  • G(Global):模块级别定义的变量

  • B(Built-in):Python 内置的变量(如printlen

简单说:Python 找变量时,先在本函数里找,找不到再去外层找,一层一层往外翻。

全局变量和局部变量

从名字上看,一个在全局(大范围)使用,一个是在局部(小范围)使用。

全局变量:在函数和类定义之外声明的变量。作用域为定义的模块,从定义位置开始到模块结束。

局部变量:在函数内部声明的变量(包括形参),只能在该函数中使用,外部无法使用。

案例——全局和局部变量

函数内部访问全局变量

# 定义一个全局变量 name = 'Tom' # 定义一个方法,打印全局变量 def show(): # 函数内部可以直接访问全局变量 print(name) show() # 输出: Tom

函数外部访问局部变量

# 定义一个函数 def show(): # 定义一个局部变量 name = 'Tom' print(name) print(name) # 错误:NameError: name 'name' is not defined

既然函数内部可以访问全局变量,那么我们现在在函数内部修改全局变量【需要使用 global 关键字】

# 定义一个全局变量 name = 'Tom' # 定义一个方法,打印全局变量 def show(): # 函数内部修改全局变量 name = 'Jerry' print(name) show() # 输出:Jerry print(name) # 输出: Tom # 我们发现,在函数外面定义的全局变量并没有因为在函数内部发生改变而改变,仍然是原来的“Tom” print('-'*30) # 正确的方式是: name1 = 'Tom1' def show1(): # 函数内部修改全局变量 global name1 name1 = 'Jerry1' print(name1) show1() # 输出:Jerry1 print(name1) # 输出: Jerry1

🤫 避坑总结

1.缩进问题:Python中是依靠缩进区分代码块的,函数体内部的代码必须缩进,且缩进量保持一致,否则导致语法错误。

2.调用顺序和局限:不是只要定义了函数就可以随时随地使用。必须先定义函数,然后才能调用它,并且如果想使用别的文件中的方法,直接在当前文件中调用是不可行的。它是先将含有该方法的文件进行封装(封装成一个类或模块),通过导入模块和实例化类,来调用该方法。

3.return 语句:函数没有 return 语句是不是没有返回值?错,没有 return 语句,也有返回值,默认返回 None。其实所有的函数都有返回值,只是有的函数不需要返回指定的数据,所以可以不需要写 return 语句,让他默认返回None即可。

4.print 与 return 区别:print 只是将结果输出到控制台,方便人查看;而 return 是将结果返回给调用者,供程序后续使用,一个函数可以没有 print ,但是如果需要返回值处理结果,就必须有 return 。

说明
函数定义了不调用写 def 只是“造工具”,必须用 函数名() 才会执行
return 后还写代码return 是重点,后面的代码永远不会执行
默认参数使用 [] 或 {}会导致多次调用共享同一个对象,应该使用 None 代替
函数内直接改全局变量需要先使用 global 声明,否则Python认为是局部变量
参数顺序写错正确顺序:位置参数 -> 默认参数 -> *args -> **kwargs

🥳三条学习心法

心法 1:参数 + return > global

能用参数传进去、用 return 传出来,就绝不用 global。

全局变量是"隐形炸弹"——程序小没问题,项目大了谁改了值根本找不到。参数和 return 让数据流动看得见、管得住

心法 2:函数要"专一"

一个函数只做一件事,名字就要让人一眼看懂。

def process_data_and_save_and_log()
def save_data()+def log_event()

函数越"专一",复用性越强,调试越轻松。

心法 3:默认参数用不可变对象

def f(lst=None)永远比def f(lst=[])安全。

Python 的默认参数在函数定义时只创建一次,用可变对象(列表、字典)会导致多次调用共享同一个对象,产生难以察觉的 Bug。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/20 4:07:07

企业级AI选型决策指南:Gemini Ultra在金融文档解析、代码生成、多模态检索三大场景的ROI实测(含TCO测算表)

更多请点击: https://codechina.net 第一章:企业级AI选型决策框架与Gemini Ultra定位解析 企业在构建AI能力体系时,需超越单一模型性能指标,转向系统性、可治理、可持续的选型决策框架。该框架涵盖五大核心维度:任务适…

作者头像 李华
网站建设 2026/5/20 4:04:06

Tabbit:美团Tabbit AI浏览器实测:从“看网页”到“替我干活”

一、核心主旨 Tabbit是一款AI原生浏览器,通过深度整合上下文理解、智能任务执行和高效信息管理功能,旨在成为用户的生产力工具,而非仅仅是网页浏览工具。 二、核心亮点 2.1 标签管理 随时唤起 AI,结合上下文精准回答。 智能标签…

作者头像 李华