定义函数
语法:使用关键字 def
def 函数名(参数):
代码1
代码2
......
调用函数
语法:
函数名(参数)
注意:不同的需求,参数可有可无。在Python中,函数必须先定义后使用
示例:
# 定义函数
def hello(name):
print("Hello my name is " + name)
# 调用函数
hello("Tom") # 打印 Hello my name is Tom
函数的形参和实参
形参:定义函数的同时定义了参数
实参:调用函数时传入参数的真实数据叫实参。
函数的返回值
语法:关键字 return
def 函数名():
return 返回值
示例:
# 定义函数
def add(a, b):
return a + b
# 调用函数
result = add(1, 2)
print(result) # 打印 3
函数的多个返回值
语法:多个返回值使用英式逗号分割
def 函数名():
return 返回值1, 返回值2, 返回值n
注意:
1,多个变量接收函数多个返回值,变量和返回值顺序一一对应。
2,一个变量接收函数多个返回值,返回的变量类型默认是元组类型。3,return 可以返回列表、元组或者字典,用于表示返回多个值。
示例:
# 定义函数
def test():
return 1, 10, 'a'
# 多个变量接收函数多个返回值,变量和返回值顺序一一对应
a, b, c = test()
print(a) # 1
print(b) # 10
print(c) # a
# 一个变量接收函数多个返回值,返回的变量类型是元组类型
t1 = test()
print(t1) # (1, 10, 'a')
函数的说明文档
定义语法:
def 函数名(参数):
""" 说明⽂档的位置,必须是函数内部第一行的注释"""
代码
......
使用语法:
help(函数名) # 使用内置函数help,查看函数说明文档
示例:
# 定义
def add(a, b):
"""加法运算,返回运算结果"""
return a + b
# 查看函数说明文档
help(add)
变量的作用域
-
局部变量
局部变量是定义在函数体内部的变量,即只在函数体内部⽣效。局部变量的作用是在函数体内部,临时保存数据,即当函数调⽤完成后,则销毁局部变量。
-
全局变量
全局变量是在函数体内、外都能⽣效的变量。
修改全局变量,使用 global 关键字
a = 100
def testA():
a = 200
print(a) # 打印函数内变量a,这时a是局部变量,修改a=200,不影响全局变量a的值
testA()
print(a) # 打印 100,在testA中修改的值,不影响全局变量a
# 演示局部内修改全局变量的值
def testB():
# 使用 global 关键字声明a为全局变量
global a
a = 200 # 声明后再修改变量a的值,此时就是修改全局变量a的值
print(a) # 打印 200
testB()
print(a) # 打印 200
函数的参数
-
位置参数
调用函数时根据函数定义的参数位置来传递参数。例如形参有2个,实参就需要传入2个。形参实参数据按照顺序一一对应。
示例:
def hello(name, age):
print(f"您的名字是{name}, 年龄是{age}")
hello("Tom", 20) # 您的名字是Tom, 年龄是20
-
关键字参数
函数调用通过“键=值”形式加以指定。可以让函数更加清晰、容易使用。函数调用时,如果有位置参数,位置参数必须在关键字参数的前面,但关键字参数之间不存在先后顺序。
示例:
def hello(name, age, gender):
print(f"您的名字是{name}, 年龄是{age}, 性别是{gender}")
hello("Tom", gender="男", age=20) # 您的名字是Tom, 年龄是20, 性别是男
-
缺省参数
缺省参数也叫默认参数,用于定义函数时,为参数提供默认值,调用函数时缺省参数不传值,此时使用参数的默认值。缺省参数传值时使用传入的值(注意:定义函数和调用函数时,默认参数要写在所有参数的后面)。
def hello(name, age, gender='男'):
print(f"您的名字是{name}, 年龄是{age}, 性别是{gender}")
hello("Tom", 20) # 您的名字是Tom, 年龄是20, 性别是男
hello("Jerry", 19, '女') # 您的名字是Jerry, 年龄是19, 性别是女
-
可变参数
可变参数也叫不定长参数。用于不确定调用的时候会传递多少个参数(不传参也可以)的场景。此时,可以包裹(packing)位置参数,或者包裹关键字参数,来进行参数传递(组包的过程),会显得非常方便。
可变参数有两种类型:
- 包裹位置参数
- 包裹关键字参数
1. 包裹位置参数
def hello(*args):
print(args) # args是元组类型
hello(100) # (100,)
hello('Tom', 'John', 'Smith') # ('Tom', 'John', 'Smith')
2. 包裹关键字参数
def hello(**kwargs):
print(kwargs) # kwargs 是字典类型
hello(name="Tom", age=18) # {'name': 'Tom', 'age': 18}
拆包
组包是将零散的数据组合成一个元组或者列表或者字典过程,拆包就是将一个组合的数据拆成零散的变量数据。
-
元组拆包
def hello():
return 100, 200
a, b = hello()
print(a) # 100
print(b) # 200
-
字典拆包
dict1 = {'name': 'Tom', 'age': 20}
# 拆包,得到字典的key
a, b = dict1
print(a) # name
print(b) # age
# 通过key,得到value
print(dict1[a]) # Tom
print(dict1[b]) # 20
交换变量
a = 10
b = 20
a, b = b, a
print(a) # 20
print(b) # 10
引用传递和值传递
-
引用传递
在函数传递变量的过程中,引用传递的是变量的引用地址(栈内存空间指向存储变量数据的堆内存地址),并不是变量本身。这意味着函数内部对变量数据的修改会影响原变量数据。
-
值传递
值传递是指在函数传递变量的过程中,程序把变量值复制了一份存储在新的堆内存地址中(新创建了一个变量,变量的值相同)后把新创建的变量本身传入到函数中,当函数对传入的变量值进行了修改后,不影响原变量的数据,原数据不变。
注意:
- 在Python中,数据的传递都是通用引用的方式传递的,没有值传递没有值传递没有值传递。
- 在引用传递过程中,原有的变量值是否改变又取决于变量的数据类型是可变类型还是不可变类型
- 对于不可变对象,修改操作会创建新的对象,因此看起来像是值传递。
- 对于可变对象,修改操作会影响到原来的对象,体现了引用传递的特性。