函数介绍:
概述:
函数也叫方法, 就是把 一些具有独立功能的代码封装到一起, 使其称为具有特殊功能的代码集.
函数: function, 方法: method
例如:
独立功能: 拿牙刷, 挤牙膏, 刷上排牙, 刷下排牙, 漱口
代码集: 刷牙
作用:
1. 模块化编程, 方便我们进行管理.
2. 提高代码的复用性.
格式:
def 函数名(形式参数1, 形式参数2...):
函数体
return 具体的返回值
格式解释:
def 固定写法, defined, 定义的意思.
函数名 类似于变量名, 见名知意即可.
形参列表 表示调用函数, 应该传入什么内容(值)
函数体 具体的逻辑代码, 就是以前我们写的if, while, for, 容器...
return 作用1: 结束方法的(类似于break) 作用2: 可以把函数的执行结果进行返回.
细节:
1. 函数必须先定义, 然后才能调用.
2. 定义函数小技巧, 三个明确:
明确函数名
明确形参列表
明确返回值
3. 调用函数小技巧, 三个步骤
写 函数名()
传参, 要什么给什么, 不要就不给.
接收返回值, 返回什么就接收什么, 不给就不接收.
4. 如果函数没有明确的返回值, 则return可以省略不写.
5. 函数必须调用, 才会执行.
# 定义函数.
def call():
print('----- 拨号 -----')
print('拨号方手机 发送信号包 到就近的基站')
print('拨号方就近基站 会解析信号包, 找到 接收方就近的基站')
print('两个基站之间通过 底下电缆的形式 传输信号包')
print('接收方就近的基站 发送信号包到 接收方手机')
print('----- 忙音等待, 嘟嘟嘟 -----')
# return # 没有返回值, 可以省略不写.
# 调用函数.
call()
函数说明文档:
概述:
函数的说明文档也叫 文档说明, 就是解释函数的 参数, 作用, 返回值的.
格式:
在函数内的第一行, 用 三引号的写法来实现即可, 可以是双引号(推荐), 也可以单引号.
如何查看说明文档:
help(函数名)
鼠标放到函数上, 点击: ctrl + Q
def get_sum(a, b):
"""
该函数的作用.
:param a: 该参数的含义
:param b: 该参数的含义
:return: 返回值的含义
"""
sum = a + b
return sum
参数解释:
概述:
定义函数的时候, 写的参数叫: 形式参数, 简称: 形参, 形容调用 函数 需要传入什么值.
调用函数的时候, 写的参数叫: 实际参数, 简称: 实参, 表示 实际参与运算的数据.
# 定义函数
def get_sum2(a, b): # 形参, 形容调用函数需要给什么值
"""
该函数用于计算两个整数和
:param a: 求和计算的第1个整数
:param b: 求和计算的第2个整数
:return: 无
"""
sum = a + b
print(f'求和结果为: {sum}')
# 调用函数
get_sum2(11, 22) # 33, 11 和 22 叫 实际参数(实参), 表示实际参与运算的数据.
返回值解释:
概述:
返回值指的是 函数操作完毕后, 需要返回给 调用者 1个什么结果.
格式:
在函数内部通过 return 返回值 这个格式即可返回.
细节:
在哪里调用函数, 就把返回值返回到哪里.
函数-嵌套调用
概述:
函数的嵌套指的是 函数的嵌套调用, 并不是函数的嵌套定义.
例如: 在 func_B 函数中 调用 func_A 这个函数, 就叫: 函数的嵌套调用.
# 1. 定义func_A()函数.
def func_A():
print('----- func_A start -----') # 2
print('我是 funcA函数 ') # 3
print('----- func_A end -----') # 4
# 2. 定义func_B()函数.
def func_B():
print('----- func_B start -----') # 1
# 3. 在这里调用 funcA()函数.
func_A()
print('----- func_B end -----') # 5
# 4. 在main函数中, 调用 func_B()函数, 观察程序的打印结果.
# main函数是程序的主入口, 所有代码的执行都是从这里开始的.
# main方法可以省略不写(建议写), Python解释器底层执行的时候, 会自动帮我们加.
if __name__ == '__main__':
func_B()
变量的作用域
概述:
变量的作用域指的是 变量的哪里能用, 哪里不能用, 即: 变量的作用区间.
分类:
局部变量: 定义在函数内 或者 函数形参列表中的 变量.
全局变量: 定义在函数外的变量, 或者用 global 关键字修饰的变量.
面试题:
局部变量 和 全局变量的区别?
答案:
1. 定义位置不同.
局部变量: 定义在函数内 或者 函数形参列表中的 变量.
全局变量: 定义在函数外的变量, 或者用 global 关键字修饰的变量.
2. 在内存中的存储位置不同.
局部变量: 存储在 堆区.
全局变量: 存储在 方法区.
3. 生命周期不同.
局部变量: 随着函数的调用而存在, 随着函数的调用完毕而消失.
全局变量: 随着 .py文件加载而存在, .py文件从内存中移除而消失.
细节:
使用变量遵循就近原则, 局部位置有就直接使用, 没有就去 全局位置找, 有就使用, 没有就报错.
# 案例1: 演示 局部变量的生命周期.
def func1():
a = 10 # 局部变量
print(f'a: {a}')
# 调用 func1()函数.
func1()
# 报错, 超出了 局部变量的作用域
# print(f'在func1()函数外, 调用变量a: {a}')
# 案例2: 演示 全局变量的生命周期.
b = 100
def func2():
print(f'func2函数, b: {b}')
def func3():
print(f'func3函数, b: {b}')
# 调用函数
func2()
func3()
# 案例3: 演示global关键字.
c = 66
def func4():
print(f'func4函数, c: {c}')
def func5():
global c # global声明的变量, 属于: 全局变量. 不写global, 下述的c是 局部变量.
c = 200
print(f'func5函数, c: {c}') # 使用变量遵循 就近原则.
# 调用函数
func4() # 66
func5() # 200
func4() # 200
函数传递
1. 函数的返回值可以作为 (另一个函数的)参数进行传递.
2. 函数可以作为 (另一个函数的)参数进行传递.
# 演示 1. 函数的返回值可以作为 (另一个函数的)参数进行传递.
def fun1():
return 100 # 返回1个结果 100
def fun2(num): # 需要1个参数
print(num)
fun2(fun1()) # 函数的返回值可以作为 (另一个函数的)参数进行传递.
# 演示 2. 函数可以作为 (另一个函数的)参数进行传递.
def get_substract(a, b):
return a - b
def calculate(a, b, fn):
"""
自定义函数, 模拟计算器, 传入什么 函数(对象), 就做什么操作.
:param a: 要操作的第1个整数
:param b: 要操作的第2个整数
:param fn: 具体的操作规则
:return: 计算结果.
"""
return fn(a, b)
print(calculate(10, 20, get_sum))
print(calculate(10, 20, get_substract))
函数参数-位置参数
Python中 函数的参数写法 主要有如下的四种:
位置参数
关键字参数
默认参数(缺省参数)
不定长参数
细节:
1. 位置参数 和 关键字参数 是针对于 实参 来讲的.
2. 缺省参数 和 不定长参数 是针对于 形参 来讲的.
位置参数:
实参的个数和顺序必须和形参保持一致.
# 1. 定义函数 user_info(), 接收三个参数, 打印自己的信息: name, age, address
def user_info(name, age, address):
print(f'我叫: {name}, 今年 {age} 岁了, 我住在: {address}')
# main函数是程序的 主入口, 所有的代码都是从这里开始执行的.
if __name__ == '__main__':
# 2. 调用函数 user_info()
user_info('张三', 23, '北京')
user_info('张三', '北京', 23) # 不报错, 但是结果不是我们要的.
函数参数-关键字参数
关键字参数:
键 = 值 的形式来传递实参
细节:
如果有多个参数(实参), 则: 位置参数在前, 关键字参数在后(且多个关键字参数之间, 没有顺序要求)
# 1. 定义函数 user_info(), 接收三个参数, 打印自己的信息: name, age, address
def user_info(name, age, address):
print(f'我叫: {name}, 今年 {age} 岁了, 我住在: {address}')
# main函数是程序的 主入口, 所有的代码都是从这里开始执行的.
if __name__ == '__main__':
# 2. 调用函数 user_info()
# 位置参数
user_info('张三', 23, '北京')
user_info('张三', '北京', 23) # 位置参数, 故意传错位置. 不报错, 但是结果不是我们要的.
# 关键字参数, 多个关键字参数之间无顺序要求.
user_info(address='广州', name='李四', age=24)
# 如果既有关键字参数, 又有位置参数. 则: 位置参数在前, 关键字参数在后.
# user_info(address='广州', name='李四', 25) # 报错, 顺序不对.
# 位置参数 关键字参数
user_info('王五', address='深圳', age=25)
函数参数-缺省参数
缺省参数:
缺省参数也叫 默认参数, 即: 定义在 函数的形参列表的 最后.
格式:
采用 键 = 值 的形式来定义, 且必须放 形参列表的最后.
细节:
1. 调用函数时, 没有给缺省参数赋值, 则: 用缺省参数的默认值.
2. 调用函数式, 如果给缺省参数赋值, 则: 用赋的新值.
# 1. 定义函数 user_info(), 接收三个参数, 打印自己的信息: name, age, address
# def user_info(name, address='北京', age): # 报错, 缺省参数必须在 形参列表的最后.
def user_info(name, age, address='三亚'):
print(f'我叫: {name}, 今年 {age} 岁了, 我住在: {address}')
# main函数是程序的 主入口, 所有的代码都是从这里开始执行的.
if __name__ == '__main__':
# 2. 调用函数 user_info()
# 位置参数
user_info('张三', 23, '北京')
user_info('张三', '北京', 23) # 位置参数, 故意传错位置. 不报错, 但是结果不是我们要的.
# 关键字参数, 多个关键字参数之间无顺序要求.
user_info(address='广州', name='李四', age=24)
# 如果既有关键字参数, 又有位置参数. 则: 位置参数在前, 关键字参数在后.
# user_info(address='广州', name='李四', 25) # 报错, 顺序不对.
# 位置参数 关键字参数
user_info('王五', address='深圳', age=25)
# 不给默认参数传值.
user_info('王五', age=25)
函数参数-不定长参数
不定长参数:
不定长参数也叫 可变参数, 即: 参数的个数是可以变化的.
应用场景:
适用于 实参的个数不确定的情况, 就可以把 形参定义成 可变参数.
格式:
*args 只能接收所有的 位置参数, 封装到: 元组中.
**kwargs 只能接收所有的 关键字参数, 封装到: 字典中.
细节:
1. 关于实参, 位置参数在前, 关键字参数在后.
2. 关于形参, 如果两种 可变参数都有, 则: *args 在前, **kwargs 在后.
3. 关于形参, 如果既有 缺省参数 又有不定长参数, 则编写顺序为: *args, 缺省参数, **kwargs
# 需求1: 演示 不定长参数(可变参数)之 接收 位置参数.
def method01(*args): # 约定俗成, 变量名可以任意写, 但是建议写成 args
print(f'接收到的所有参数为: {args}') # 你把 args变量当做 元组来用即可.
print(type(args))
# 需求2: 演示 不定长参数(可变参数)之 接收 关键字参数.
def method02(**kwargs):
print(f'接收到的所有参数为: {kwargs}')
print(type(kwargs))
# 需求3: 同时定义两种 参数.
# 不定长(可变)参数
def method03(*args, **kwargs):
print(f'args: {args}')
print(f'kwargs: {kwargs}')
# 需求4: 同时定义 缺省参数, 不定长参数.
# 不定长参数 缺省参数 不定长参数
def method04(*args, name='张三', **kwargs):
print(f'name: {name}')
print(f'args: {args}')
print(f'kwargs: {kwargs}')
# main充当程序的 主入口.
if __name__ == '__main__':
# 调用 method01()函数.
method01(1, '张三', 23)
# method01(1, '张三', age=23) # 报错, *args 只能接收所有的 位置参数.
# 调用 method02()函数.
method02(name='张三', age=23, phone='13112345678')
# method02('李四', age=24, phone='13112345678') # 报错, **kwarg 只能接收所有的 关键字参数.
# 调用 method03()函数
# 位置参数 关键字参数
method03(10, 20, 'aa', name='王五', age=25, address='杭州')
# 调用 method04()函数
# 位置参数 关键字参数
method04(10, 20, 'aa', name='王五', age=25, address='杭州')
匿名函数
概述:
没有名字的函数 就叫 匿名函数.
格式:
变量名 = lambda 形参列表 : 函数体(只能写一行代码, 且该行代码的结果会被自动返回)
细节:
1. Python的匿名函数 类似于 Java中的Lambda表达式.
2. 匿名函数适用于简单的业务需求, 即: 函数体只有一行代码的函数.
3. 匿名函数的应用场景:
当对方法仅调用一次.
匿名函数 可以作为 函数对象 进行传递.
# 匿名函数方式实现计算两个整数.
def my_func(a, b, fn):
"""
自定义函数, 根据传入的规则, 来计算两个整数的结果.
:param a: 要操作的第1个数据
:param b: 要操作的第2个整数
:param fn: 具体的 计算规则 函数.
:return: 具体的计算结果.
"""
return fn(a, b)
# 调用 my_func()函数.
# 加
# print(my_func(10, 3, get_sum))
print(my_func(10, 3, lambda a, b : a + b))
# 减
# print(my_func(10, 3, get_sub))
print(my_func(10, 3, lambda a, b: a - b))
# 乘
print(my_func(10, 3, lambda a, b: a * b))
# 除
print(my_func(10, 3, lambda a, b: a // b))
# 最大值
# print(my_func(10, 3, lambda a, b: max(a, b)))
print(my_func(10, 3, lambda a, b: a if a >= b else b))
# 最小值
print(my_func(10, 3, lambda a, b: a if a <= b else b))
# 平均值
print(my_func(10, 3, lambda a, b: (a + b) // 2))