🔧 一、函数分类
Python中的内置函数:
https://docs.python.org/zh-cn/3.13/library/functions.html
Python中的模块:
https://docs.python.org/zh-cn/3.13/py-modindex.html
💻 二、函数的基本使用
定义函数的语法:
def 函数名(参数1, 参数2): """这是函数的说明文档""" # 函数体 return 返回值
来个最简单的例子:
def greet(): print("前端AI日志!")# 调用函数greet() # 输出:前端AI日志!
就这么简单!定义一次,想调用几次就调用几次~
🎯 三、函数的参数(重头戏!)
1. 位置参数
# 按顺序传参。使用位置参数时,不能跳过某个位置的参数,去给后面的形参赋值。def introduce(name, age): print(f"我叫{name},今年{age}岁")introduce("小明", 18) # 输出:我叫小明,今年18岁
2. 关键字参数
# 不用按顺序,直接指定参数名introduce(age=20, name="小红") # 输出:我叫小红,今年20岁
3. 参数默认值
# 给参数一个默认值,不传就用默认的def buy_coffee(type="拿铁"): print(f"来一杯{type}")buy_coffee() # 输出:来一杯拿铁buy_coffee("美式") # 输出:来一杯美式# 会报错,默认参数必须要放在必选参数的后面# def buy(type="美式",food): # print(f"{food}{type}")
注意:默认参数必须要放在必选参数的后面,或者说:某个形参,一旦设置了默认值那它后面的所有形参,也必须要写默认值!
4. 可变参数
# 不确定要传几个参数时用这个:# *args:接收任意数量的位置参数,变成元组def sum_all(*args): return sum(args)print(sum_all(1, 2, 3, 4)) # 输出:10# **kwargs:接收任意数量的关键字参数,变成字典def show_info(**kwargs): print(kwargs)show_info(name="小明", age=18) # 输出:{'name': '小明', 'age': 18}# 可变位置参数、可变关键字参数,也能与其他类型的参数一起使用。def test(a,b,*args,c,**kwargs): print(a, b, args, c, kwargs)# 输出1 2 (3, 4) 5 {'d': 6, 'e': 7}test(1,2,3,4,c=5,d=6,e=7)
5. 限制传参方式
# *后面的只能用关键字参数def func(a, b, *, c, d): print(a, b, c, d)func(1, 2, c=3, d=4) # 正确# func(1, 2, 3, 4) # 报错!c和d必须用关键字参数# /前边只能用位置参数def func1(a, b, /, c, d): print(a, b, c, d)func1(1,2, c=3, d=4) # 正确func1(a=1,b=2,3,4) # 报错!a和b必须用位置参数
注意:/和*同时使用时,/必须在*的前面。
📤 四、返回值与 None
None是一个特殊的字面量,它表示:空值/无值/无意义。
None的类型是NoneType。
None 转为布尔值是False。
None不能参与数学运算,也不能与字符串拼接。
不给函数设置返回值,函数会默认返回None。
返回值用 return:
def add(a, b): return a + bresult = add(3, 5)print(result) # 输出:8
特殊的 None:
def say_hello(): print("Hello")result = say_hello()print(result) # 输出:None(因为没有return)
🌍 五、作用域:全局 vs 局部
局部变量:
在函数内部定义的变量,外面用不了:
a = 100def test(): x = 10 # 局部变量 x += 1 a = 200 print(x)test()# print(x) # 报错!x在外面不存在# print(a) # 100,函数中的a和函数外的a不是一个变量,这与前端js中不一样# 局部作用域和局部变量,会在函数调用时创建,在函数执行结束后自动销毁test() # 此时输出依然是 11
全局变量:
在函数外部定义的变量,函数里能用,但要修改得加 global:
y = 20 # 全局变量def test(): global y y += 1 print(y)test()print(y) # 输出:21# 全局作用域和全局变量,会在程序开始时创建,在程序结束后销毁test()print(y) # 输出:22
🔄 六、函数的嵌套调用
函数可以调用函数,就像套娃一样:
def test1(): print("进入 test1") test2() print("退出 test1")def test2(): print("进入 test2") test3() print("退出 test2")def test3(): print("进入 test3") print(">>> 正在执行 test3") print("退出 test3")test1()# 输出:# 进入 test1# 进入 test2# 进入 test3# >>> 正在执行 test3# 退出 test3# 退出 test2 👇 下图讲清楚了为啥先输出test2# 退出 test1 👇 下图讲清楚了为啥后输出test1
下图讲清楚了函数嵌套调用执行过程(栈:先进后出,前端JS也是如此)
♾️ 七、递归:函数自己调自己
递归调用(简称递归):是指函数自己调用自己的一种操作。
经典例子:计算阶乘
def factorial(n): if n == 1: return 1 return n * factorial(n - 1)print(factorial(5)) # 输出:120# 栈:先进后出示例def hello(n): if n > 0: hello(n-1) print(f'你好{n}')hello(2)# 输出,这里与六中图里原理一样,栈:先进后出# 你好0# 你好1# 你好2
“先打印后递归”和“先递归后打印” 的代码,都会触发压栈,只是打印时机不同👇👇👇
📚 八、给函数写说明文档
好的函数一定要有说明文档,方便别人(也方便未来的自己)看懂:
def add(a, b): """ 计算两个数的和 参数: a (int/float): 第一个数 b (int/float): 第二个数 返回: int/float: 两数之和 """ return a + b# 查看说明文档print(add.__doc__)help(add)
🎮 九、综合案例:一个完整的计算器
def calculator(a, b, operation="+"): """ 简单的计算器函数 参数: a (int/float): 第一个数 b (int/float): 第二个数 operation (str): 操作类型:+, -, *, / 返回: int/float: 计算结果 """ if operation == "+": return a + b elif operation == "-": return a - b elif operation == "*": return a * b elif operation == "/": if b == 0: return "错误:除数不能为0" return a / b else: return "错误:不支持的操作"# 测试一下print(calculator(10, 5)) # 15print(calculator(10, 5, "-")) # 5print(calculator(10, 5, "*")) # 50print(calculator(10, 5, "/")) # 2.0print(calculator(10, 0, "/")) # 错误:除数不能为0