函数的创建函数(function)就是用于完成特定功能的代码块
使用函数的原因:
- 增强代码的复用性
- 封装代码的实现,保护数据的安全
在python中定义函数要使用关键字def,使用return 表达式 返回内容
在函数定义的过程中要注意:
- 函数定义要以def开头,一个空格后跟函数名和圆括号(),再接冒号
- 任何参数的传入要写在圆括号里面,多个参数要以 逗号(,)间隔
- 函数的内容以冒号开始,函数内的代码要保持缩进一致
- 函数return结束,没有return执行最后一行结束,默认放回None。
格式:
def 函数名(参数列表):
# 函数体
# 代码实现
return 表达式
例子:
>>> def sum(num1,num2): ... return num1 + num2 ...函数的调用
函数存在的目的就是被调用,想要调用一个函数就要以函数名加圆括号的形式进行调用,想要正确的调用一个函数除了函数名要正确外,参数列表必须要一一对应,否则会报错
>>> sum(1) Traceback (most recent call last): File "", line 1, in TypeError: sum() missing 1 required positional argument: 'num2' >>> sum('a', 2) Traceback (most recent call last): File " ", line 1, in File " ", line 2, in sum TypeError: can only concatenate str (not "int") to str >>> sum(1,2) 3
sum(num1,num2)函数我们需要两个int类型参数,如果给一个,就会报错,给的类型不对也会报错,只有数量和类型都没问题才会运行这个函数.
函数的参数函数通常都有参数,用于将外部数据的传入函数内部进行处理。
python函数的参数有5种:
- 位置参数(positional arguments,官方定义,相当于其他编程语言的参数)
- 默认参数(类似与C++的默认参数)
- 动态参数
- 关键字参数
传入不同的参数会有不同的结果发送
def change_num(num):
num += 1
print(num)
num = 0
change_num(num)
print(num)
----------------------------------
1
0
def change_num(num_list):
num_list.append(1)
num_list = [1,2]
print(num_list)
change_num(num_list)
print(num_list)
----------------------------------
[1, 2]
[1, 2, 1]
为什么?
因为,Python的数据类型分可变数据类型和不可变数据类型。
num是一个不可变对象一旦你改变num的值,num就会创建一个新的数字对象
Python的函数参数传递的是实际对象的内存地址。外部num和内部num指向同一地址, 但是改变参数num的值的时候,会使它指向一个新的内存空间,但是外部num指向的内存地址不会被改变。
list是可变的数据类型
传递参数时,先将实际参数列表的地址传参数num_list
函数内通过参数num_list改变list内的值时,并不会创建新的内存空间后操作,而是直接在原有的内存空间中进行操作,这要的话,你在函数内对列表的修改实际就是作用在原对象上
-
位置参数
位置参数就是其他语言的参数,所有参数都要遵循位置一一对应的原则
def max_min(a, b, c): lis = [a, b, c] min = lis[0] max = 0 for i in lis: if i > max: max = i if i < min: min = i return min, max print(max_min(2, 1, 3)) ---------------------------------- (1, 3) # 由此可见当return返回多个参数时,会将数据封装为一个元组对象 -
默认参数
python的默认参数完全等同于C++的默认参数,引入默认参数是为了在某些情况向提供便利
语法:形参名 = 默认值
def print_info(name, age, sex='女'): print(name + '-->' + str(age) + '--->' + sex) print_info('剑姬', 18) print_info('剑魔', 20, '男')默认参数的优势:如果在男女比例均衡的地方,和普通参数一致,但是如果出现只有男或女,默认对象会有很大的优势
使用时注意点:
-
默认参数要写在最右端,不然会产生歧义(编译不通过)
>>> def print_info(sex='女', name, age): File "
", line 1 def print_info(sex='女', name, age): ^ SyntaxError: non-default argument follows default argument -
默认参数一定要是不可变对象(int、float、str、tuple)
def list_default(lis = []): lis.append('Python') return lis print(list_default()) print(list_default()) ---------------------------------- ['Python'] ['Python', 'Python']python不会将默认参数使用后直接释放,多次调用含默认参数的函数,就会对参数进行多次修改
改进方法使用None:
def list_default(lis=None): if lis is None: lis = [] lis.append('Python') return lis print(list_default()) print(list_default()) ---------------------------------- ['Python'] ['Python']
-
-
动态参数
动态参数顾名思义,就是传入的参数的个数是动态的,python的动态参数分两种,分别是 *args 和 **kwargs,它们的区别是一个*和两个*的区别,后面只是名字而已
注意:动态参数必须在位置参数和默认参数的后面
-
*args
表示可以接收任意个参数,调用时,以元组的形式传递
def args_info(*args): print(args) print(type(args)) args_info(1, 2, 3) args_info([1, 2, 3]) ---------------------------------- (1, 2, 3)([1, 2, 3],) 可见,无论是多个参数,还是一个参数,都会被打包成元组进行传递
那如果我们希望将一个列表,一个一个的传入,而不是整个列表一次性传入呢?
使用*对列表进行标记
def args_info(*args): print(args) print(type(args)) args_info(*[1, 2, 3]) ---------------------------------- (1, 2, 3) -
**kwargs
表示可以接收任意个键值对参数,调用时,以字典的形式传递
def kwargs_info(**kwargs): print(kwargs) print(type(kwargs)) kwargs_info(name='python') kwargs_info(lis=[1, 2, 3]) kwargs_info(1, 2, 3) ---------------------------------- {'name': 'python'}{'lis': [1, 2, 3]} Traceback (most recent call last): File " ", line 1, in TypeError: kwargs_info() takes 0 positional arguments but 3 were given 同样和*args一样如果你想提供一个字典进行传参,可以直接在字典前面加上**
-
-
关键字参数
对与*args和**kwargs方法我们可以传入任意的参数,这样的传入参数虽然灵活性很大,但是风险也很大,可控性差,必须要对自己需要的参数,进行过滤和判断。
例如:我们只需要,年龄、姓名的性别,就需要自己写代码进行判断
def print_info(name, age, **kwargs): if 'sex' in kwargs: print(name + '-->' + str(age) + '--->' + kwargs['sex'])这里我们可以使用*进行分隔
def print_info(name, age, *, sex): pass print_info('剑魔', 20, sex='男')这里要注意,如果已经有*args参数了,就不需要使用*进行分隔了
def print_info(name, age, *args, sex): pass print_info('剑魔', 20, sex='男')
return语句的意思就是函数到此为止,并且返回return后面表达式的结果。**一旦函数执行到return就会直接结束,无论return后面有多少内容都不会被执行,直接跳出函数体。**哪怕它在一个循环中。
return返回的可以是那些对象?
- 什么都不放回:return
- 基本数据类型:return 基本数据类型的值
- 表达式:return 任意类型表达式
- 返回表达式的计算结果
- 函数:return 函数
- 多个返回值:return 值1, 值2, ....
如果你需要return可以返回任何python对象
return语句
return语句的意思就是函数到此为止,并且返回return后面表达式的结果。**一旦函数执行到return就会直接结束,无论return后面有多少内容都不会被执行,直接跳出函数体。**哪怕它在一个循环中。
return返回的可以是那些对象?
- 什么都不放回:return
- 基本数据类型:return 基本数据类型的值
- 表达式:return 任意类型表达式
- 返回表达式的计算结果
- 函数:return 函数
- 多个返回值:return 值1, 值2, ....
如果你需要return可以返回任何python对象



