Python函数
函数介绍
定义: 函数是指将一组语句的集合通过一个名字(函数名)封装起来,要想执行这个函数,只需调用其函数名即可。
特性:减少重复代码、使程序变的可扩展、使程序变得易维护。
函数的结构与调用
函数的结构
def 函数名(): 函数体
def 关键词开头,空格之后接函数名称和圆括号(),最后还有一个":"。
def 是固定的,不能变,他就是定义函数的关键字。
空格 为了将def关键字和函数名分开,必须空(四声),当然你可以空2格、3格或者你想空多少都行,但正常人还是空1格。
函数名:函数名只能包含字符串、下划线和数字且不能以数字开头。虽然函数名可以随便起,但我们给函数起名字还是要尽量简短,并且要具有可描述性。
括号:是必须加的,括号是参数。
下面的函数体一定全部都要缩进,这代表是这个函数的代码。
#函数定义 def mylen(): """计算s1的长度""" s1 = "hello world" length = 0 for i in s1: length = length+1 print(length)
函数的调用
使用函数名加小括号就可以调用了 写法:函数名() 这个时候函数的函数体会被执行
通过上面的动态图大家可知,只有解释器读到函数名() 时,才会执行此函数,如果没有这条指令,函数里面即使有10万行代码也是不执行的。
而且是这个指令你写几次,函数里面的代码就运行几次。
函数的注释
注释:每一个函数都应该对功能和参数进行相应的说明,应该写在函数下面第一行。以增强代码的可读性。
def func(): ''' 这个函数实现了什么功能 参数1: 参数2: :return: 是字符串或者列表的长度 ''' pass
函数的返回值
没有返回值
不写返回值(不写return)
#函数定义 def mylen(): """计算s1的长度""" s1 = "hello world" length = 0 for i in s1: length = length+1 print(length) #函数调用 str_len = mylen() #因为没有返回值,此时的str_len为None print('str_len : %s'%str_len)
注:不写return的情况下,会默认返回一个None:我们写的第一个函数,就没有写return,这就是没有返回值的一种情况。
只写返回值(只写return)
def ret_demo(): print(111) return print(222) ret = ret_demo() print(ret)
注:一旦遇到return,结束整个函数。
def ret_demo(): print(111) return None print(222) ret = ret_demo() print(ret)
注:和上面的两种情况一样,我们一般不这样写。
返回一个值
# 函数定义 def mylen(): """计算s1的长度""" s1 = "hello world" length = 0 for i in s1: length = length + 1 return length # 函数调用 str_len = mylen() print('str_len : %s' % str_len) # str_len : 11
注:1.可以返回任何数据类型 2.只要返回就可以接收到 3.如果在一个程序中有多个return,那么只执行第一个
返回多个值
def ret_demo2(): return 1, ['a', 'b'], 3, 4 # 返回多个值,用多个变量接收 # 返回多个值,用一个变量接收 ret = ret_demo2() # 相当:ret = (1, ['a', 'b'], 3, 4) print(ret) # 返回的多个值会被组织成元组被返回,返回几个值,就用几个变量接收 a, b, c, d = ret_demo2() # 相当:a, b, c, d = (1, ['a', 'b'], 3, 4) print(a, b, c, d)
函数的参数
我们告诉mylen函数要计算的字符串是谁,这个过程就叫做 传递参数,简称传参,我们调用函数时传递的这个“hello world”和定义函数时的s1就是参数。
# 定义函数时的s1,只是一个变量的名字,被称为形式参数,因为在定义函数的时候它只是一个形式,表示这里有一个参数,简称形参。 def mylen(s1): """计算s1的长度""" length = 0 for i in s1: length = length + 1 return length # 调用函数时传递的这个“hello world”被称为实际参数,因为这个是实际的要交给函数的内容,简称实参。 str_len = mylen("hello world") print('str_len : %s' % str_len)
传递多个参数
参数可以传递多个,多个参数之间用逗号分割。
def mymax(x,y): the_max = x if x > y else y return the_max ma = mymax(10,20) print(ma)
位置参数
站在实参角度
1、按照位置传值
就是从左至右,实参与形参一一对应。
def mymax(x,y): #此时x=10,y=20 the_max = x if x > y else y return the_max ma = mymax(10,20) print(ma) # 20
2、按照关键字传值
def mymax(x,y): #此时x = 20,y = 10 print(x,y) the_max = x if x > y else y return the_max ma = mymax(y = 10,x = 20) print(ma)
3、位置、关键字形式混着用
def mymax(x,y): #此时x = 10,y = 20 print(x,y) the_max = x if x > y else y return the_max ma = mymax(10,y = 20) print(ma)
站在形参角度
位置参数必须传值
def mymax(x,y): #此时x = 10,y = 20 print(x,y) the_max = x if x > y else y return the_max #调用mymax不传递参数 ma = mymax() print(ma) #结果 TypeError: mymax() missing 2 required positional arguments: 'x' and 'y'
默认参数
1、默认参数的定义
定义了默认参数后,在函数调用时不需要再传入,默认参数放在最后面
def info(name,age,country = 'CN'): #country定义了一个默认参数 print('姓名:{},年龄:{},国籍:{}'.format(name,age,country)) info('derek',22) #调用时,没穿实参countrty,就用默认的参数 结果:姓名:derek,年龄:22,国籍:CN
2、参数陷阱
默认参数是一个可变数据类型
def defult_param(a, l=[]): l.append(a) print(l) defult_param('小白') # ['小白'] defult_param('小黑') # ['小白', '小黑']
动态参数
动态参数分为两种:动态接受位置参数 *args,动态接收关键字参数**kwargs。
*args:动态接收位置参数
按位置传值多余的参数都由args统一接收,保存成一个元组的形式
def fuck(name, age, *args): # *args会把多传入的参数变成一个元祖形式 print(name, age, args) fuck('xiaobai', 20, '男', '篮球') # xiaobai 20 ('男', '篮球')
**kwargs:动态接收关键字参数
按关键字传值多余的参数都由kwargs统一接收,保存成一个字典的形式
# **kwargs def fuck(**kwargs): # **kwargs 会把多传入的参数变成一个dict形式 print(kwargs) fuck(name = 'xiaobai',age= 20) # {'name': 'xiaobai', 'age': 20}
注:形参的排序——1.位置参数(必须传)2.*args:可以接收任意多个位置参数 3.默认参数:可以不传 4.**kwargs:可以接收多个关键字参数
* 的魔性用法
聚合
在函数定义时,如果我只定义了一个形参称为args,只能当做一个位置参数对待,它只能接受一个参数。
def eat(args): print(args) eat('abcdef') # abcdef
如果我给其前面加一个* 那么args可以接受多个实参,并且返回一个元组。 (**kwargs也是同理将多个关键字参数转化成一个字典返回)所以在函数的定义时: *起到的是聚合的作用。
打散
# 可迭代对象打散 print(*[1, 2, 3, 4, 5, 6]) # 1 2 3 4 5 6 print(*'asafasaffa') # a s a f a s a f f a s1 = 'alex' l1 = [1, 2, 3, 4] tu1 = ('小白', '小米', '小黑',) def func(*args): print(args) # ('a', 'l', 'e', 'x', 1, 2, 3, 4, '小白', '小米', '小黑') func(*s1, *l1, *tu1) # 字典的打散 dic1 = {'name': '小白', 'age': 18} dic2 = {'hobby': '喝茶', 'sex': '男'} def func(**kwargs): print(kwargs) # {'name': '小白', 'age': 18, 'hobby': '喝茶', 'sex': '男'} func(**dic1, **dic2)
处理剩下的元素
除了在函数中可以这样打散,聚合外,函数外还可以灵活的运用:
# 之前的分别赋值 a,b = (1,2) print(a, b) # 1 2 # 其实还可以这么用: a,*b = (1, 2, 3, 4,) print(a, b) # 1 [2, 3, 4] *rest,a,b = range(5) print(rest, a, b) # [0, 1, 2] 3 4 print([1, 2, *[3, 4, 5]]) # [1, 2, 3, 4, 5]