本期呢就让我们一起来学习python中的函数部分
一、函数的定义
def 函数名(形参1,形参2,形参n):
代码块(函数体)
函数名的命名规则和变量名命名规则一样
另外,函数的本质就是一段有特定功能,可以重复使用的代码,例如下面这个统计字符串长度的函数:
def Count_len(s):
A = 0
for i in s:
A += 1
return A
print(Count_len("Hellopython"))
#使用自定义函数输出结果
11
print(len("Hellopython"))
#使用python内置统计字符串长度的函数的输出结果
11
在这个例子中,函数名为Count_len,期括号内的s为形式参数,简称形参,形参的值在函数调用时被传入,函数体就是带有字母A的部分,从该例子可看出函数可以用来保存代码,在需要用到这些代码时,可以对其进行重复的调用。那么接着,我们来学习如何调用函数。
二、函数的调用
语法:
函数名()
注意:函数要先创建才能被调用
依然是统计字符串的长度这个例子,只不过我们对其稍加修改
def Count_len(s):
A = 0
for i in s:
A += 1
print(A)
Count_len("Hellopython")
#输出结果
11
从这个例子可看出,要想调用函数,只需要在函数名后面加个小括号即可,另外,函数在调用时也能进行传递参数处理。接下来区分两个概念:函数对象,调用函数
例如:Function 称为 函数对象
Function() 称为调用函数
这两个的区别就是函数名后是否带小括号,带小括号的被称为函数调用,不带的被称为函数对象。
知道了怎么调用函数以及如何区分函数对象和调用函数,下面我们在来学习函数的参数。
三、函数的参数
在定义函数时,可以在函数名后的括号里面定义数量不等的参数
注意:参数可有可无,可以为一个也可以为多个,但多个形参之间记得用逗号隔开
3.1形参和实参
- 形参(形式参数):定义形参就相当于在函数内部声明了变量,但并不是赋值
- 实参(实际参数):函数定义时就指定了形式参数,再调用函数时则需传递相应的实际参数,传递的实际参数会被赋值给对应得形式参数
我们来一起看一下下面的这个例子
def Assign(a,b,c): # 定义函数时指定形式参数
print('a=',a)
print('b=',b)
print('c=',c)
# 调用函数时传递实际参数
Assign(10,5,20)
#输出结果
a= 10
b= 5
c= 20
从这个例子可以看出,再创建函数时我们给函数指定了三个形式参数,那么在调用函数时相对应的就得传递三个实际参数,即函数有几个形式参数就得传递几个实际参数。另外,形式参数在函数创建时只是个形式,并没有值,在函数需要被调用时参可以确定其是何值,调用函数时传递的参数即为实际参数。
3.2 参数的传递方式
3.2.1 默认值参数
在函数创建时我们可以手动的为形式参数添加一个默认的参数值,当函数被调用时,若没有传递实际参数的值,那就输出对应的默认值;若传递了实际参数的值,那就输出传递的实际参数的值,就拿上一个例子举例:
def Assign(a,b,c=5): # 为形式参数c添加默认值5
print('a=',a)
print('b=',b)
print('c=',c)
#不为c传递实际参数
Assign(10,5)
#输出结果
a= 10
b= 5
c= 5
#为c传递实际参数
Assign(10,5,20)
#输出结果
a= 10
b= 5
c= 20
可以看出,当不为传递实际参数时,其值为默认值,当为c传递实际参数时,其值为传递的实际参数的值。下面接着介绍位置参数和关键字参数
3.2.2 位置参数和关键字参数
3.2.2.1 位置参数
位置参数就是将对应的位置的实际参数赋值给对应位置的形式参数,位置参数实际上和直接传递实际参数类似,只是在传递实际参数是需要考虑形式参数所处位置,这里就不作过多赘述,感兴趣的小伙伴可以自己稍加验证。
3.2.2.2 关键字参数
该方法不需要我们取记忆参数的顺序,只需记住参数的名字即可
还是给数字赋值这个例子
def Assign(a,b,c):
print('a=',a)
print('b=',b)
print('c=',c)
Assign(b=5,c=20,a=10) # 以关键字的方式为形参a,b,c传递参数
#输出结果
a= 10
b= 5
c= 20
可以看出,以关键字的方式传递参数时即使不按顺序传递,最终的输出结果也和按顺序传递参数的结果相同,另外,位置参数可以和关键字参数混合使用,但混合使用时,位置参数必须在关键字参数的前面,还是给数字赋值这个例子
def Assign(a,b,c):
print('a=',a)
print('b=',b)
print('c=',c)
#位置参数在关键字参数前面
Assign(10,5,c=20)
#输出结果
a= 10
b= 5
c= 20
#关键字参数在位置参数前面
Assign(a=10,5,20)
#输出结果
SyntaxError: positional argument follows keyword argument # 报错信息
可以看出,当关键字参数位于位置参数前面时,程序会报错,因此,各位小伙伴自己在练习时记得别弄错顺序。
3.3 实际参数的类型
实际参数可以是任何值,例如以下的例子:
def Function(S):
print(S)
A = True
Function(A)
#输出结果
True
B = 'python'
Function(B)
#输出结果
'python'
C = [1,2,3,4,5]
Function(c)
#输出结果
[1,2,3,4,5]
D = (1,2,'Hello',True)
Function(D)
# 输出结果
(1,2,'Hello',True)
可以看出,无论我们传递的实际参数是任何值,输出的结果都是我们传递的值,不过需要注意的是当传递的实际参数为函数对象时,输出的结果会是一串函数内存地址,感兴趣的小伙伴可以自己尝试一下,这里就直接告诉大家结论。好,我们接着学习。
3.4 可变参数(不定长参数)
3.4.1 *args
在形式参数前面加上一个星号(*) 就是可变参数,其可以接受所有的实际参数,并把实际参数的值保存到一个元组中(也称为装包),但是有个弊端,那就是只能接收位置参数。
下面来看一个例子:
# 传递的参数为位置参数
def Assign(*A):
print(A)
print(type(A))
Assign(1,2,'Hello',4,5)
# 输出结果
(1, 2, 'Hello', 4, 5)
<class 'tuple'>
#传递的参数为关键字参数
Assign(a=10,b=5,c=20)
#输出结果
TypeError: Assign() got an unexpected keyword argument 'a' # 报错信息
可以看出,最终结果是被一对小括号括起来的,与元组的形式相同,并且查看其类型后也是一个元组,这里的type()方法为python的内置方法,其作用就是查看数据的类型,当传递的参数为关键字参数程序报错。另外,注意:
1.带*号的参数只能有一个
2.带*号的参数可以和其他参数配合使用,与位置参数配合使用时得写在最后面,与关键字参数配合使用时得写在最前面
例:与位置参数配合使用时
#与位置参数配合使用,且位于前面
def Assign(*a,b,args):
print('a=',a)
print('b=',b)
print('args=',args)
Assign(1,2,3,4,5)
#输出结果
TypeError: Assign() missing 2 required keyword-only arguments: 'b' and 'args' # 报错信息
#与位置参数配合使用,且位于后面
def Assign(a,b,*args):
print('a=',a)
print('b=',b)
print('args=',args)
Assign(1,2,3,4,5)
#输出结果
a= 1
b= 2
args= (3, 4, 5)
例:与关键字参数配合使用时
# 与关键字参数配合使用且位于前面
def Assign(*a,b,args):
print('a=',a)
print('b=',b)
print('args=',args)
Assign(1,2,3,4,5,b=10,args=20)
# 输出结果
a= (1, 2, 3, 4, 5)
b= 10
args= 20
# 与关键字参数配合使用且位于后面
def Assign(a,b,*args):
print('a=',a)
print('b=',b)
print('args=',args)
Assign(a=10,b=20,1,2,3,4,5)
# 输出结果
SyntaxError: positional argument follows keyword argument # 报错信息
3.4.2 **kwargs
该方法可以将接收得参数得值保存为一个字典,字典的键就是参数得名字,字典得值就是参数得值,但是该方法有一个弊端,那就是只能接收关键字参数
例:
# 正确传递参数
def Function(**kwargs):
print('kwargs=',kwargs)
print(type(kwargs))
Function(a=10,b=5,c=20)
#输出结果
kwargs= {'a': 10, 'b': 5, 'c': 20}
<class 'dict'>
# 错误传递参数
Function(10,5,20)
#输出结果
TypeError: Function() takes 0 positional arguments but 3 were given # 报错信息
注意:**形参也是只能有一个,并且必须写在所有参数的最后面即最后一个,其命名潜规则就是kwargs
3.4.3 同时使用可变参数
*args 和 **kwargs 可以同时使用,但*args 必须写在**kwargs 之前
例:
def Function(*args,**kwargs):
print('args=',args)
print('kwargs=',kwargs)
Function(1,2,3,4,5,A=10,B=20,C=30)
#输出结果
args= (1, 2, 3, 4, 5)
kwargs= {'A': 10, 'B': 20, 'C': 30}
3.5 参数的解包
解包就是将元组或字典中的数据拆成单个数据或单个键值对,另外,字符串也可拆包,语法与元组类似
语法:
函数名(*需要拆包的元组)
函数名(**需要拆包的字典)
例:对元组 t = (1,2,3,4,5) 和字典 dict1 = {'a':10,'b':5,'c':20} 进行拆包处理,并输出拆包后的结果
def Function(a,b,c):
print('a=',a)
print('b=',b)
print('c=',c)
# 对元组拆包
t = (1,2,3)
Function(*t)
#输出结果
a= 1
b= 2
c= 3
#对字典拆包
dict1 = {'a':10,'b':5,'c':20}
Function(**dict1)
# 输出结果
a= 10
b= 5
c= 20
好了,以上就是函数参数的全部内容,下面,我们接着学习函数的返回值
四、函数的返回值
先来看这样一个例子
例:定义一个函数,求任意数字的和
def sum1(*args):
result = 0
for i in args:
result += i
return result
print(sum1(1,2,3,4))
#输出结果
10
这里的return 后面的内容就被称作函数的返回值,return 后面可以是任何数据类型,并且return只能返回单个值,但是值可以有很多元素。当不给函数写return 返回值或不写return时,该函数的返回值就会为一个空值,即None。另外,在函数中return 即代表函数执行结束,其后面的代码不会再执行。
例1:返回值为数字和字符串
def Function():
return 1,2,'Hello','python'
print(Function())
# 输出结果
(1, 2, 'Hello', 'python')
例2:返回值为函数
def Function1():
def Function2():
print('Hello')
return Function2
print(Function1())
# 输出结果
<function Function1.<locals>.Function2 at 0x00000180A3ADA700> # 函数地址
result = Function1
result()
# 输出结果
Hello
可以看出,当直接打印Function()时结果为函数Function2内存地址,因为其内部的return将函数对象Function2返回给了Function1,所以此时的Function1()的值就相当于Function2,因此,输出结果就为函数Function2的内存地址,此时需将Function1()赋值给一个变量,此变量再进行调用,实际上就是在对Function2进行调用,因此就可以输出Function2内的内容了。看到这里觉得绕的小伙伴不妨先再看一遍函数对象和调用函数的内容,这样也许能帮助你理解这一块的内容。
例3:返回值为空None
# 写return
def Function3():
return
print(Function3())
# 输出结果
None
# 不写return
def Function3():
pass
print(Function3())
# 输出结果
None
从这个例子可以看出,若仅仅写了一个return或不写return时,就等价于return None
例4:结束函数
def Function():
print('A')
print('B')
return # 结束函数,后面的代码不再执行
print('C')
print('D')
Function()
#执行结果
A
B
可以看出,由于return ,在调用函数时就执行了前两行代码,后两行代码未被执行,因此, 在函数中return 就代表函数执行结束。
五、总结
5.1 函数的优点
遇到重复功能的时候,直接调用就可以,减少了代码量,提升代码,项目 的结构性,分工明确,提高代码的可读性,遇到扩展功能时,修改比较方便
5.2 return语句的作用
结束函数,返回值,当return 语句中有指定返回值时就返回其值,当没有返回值或没有return语句时,函数默认返回值为None
注意:return 语句可以在同一个函数中出现多次,但是只要有一个执行到了,就会直接结束函数的执行
5.3 print 和 return 的区别
print仅仅只是打印,而return则是将return后面的部分作为返回值返回给函数,函数接收返回值后可以继续使用该返回值做其他操作
5.4 空值None
首先,和False不同,None不表示0,也不表示空字符串,而是表示没有值,即空值,另外,None也有属于自己的类型,即NoneType类型并且,None是NoneType数据类型的唯一值。
那么以上就是函数基础部分的所有内容,如果有写的不对的地方以及需要修改的地方,欢迎各位小伙伴指出,下期将为大家带来匿名函数的内容,觉得作者写的不错的小伙伴别错过哦~下期见