目录python
函数在编程语言中就是完成特定功能的一个词句组(代码块),这组语句能够做为一个单位使用,而且给它取一个名字。能够经过函数名在程序的不一样地方屡次执行(这叫函数的调用
)。函数在编程语言中有基本分为:预约义函数,自定义函数。预约义函数能够直接使用,而自定义函数顾名思义须要咱们本身定义函数。编程
在数学中的定义,这里就不介绍了。由于没卵用。哈哈编程语言
在编程中使用函数主要有两个优势:函数
在Python中,函数由若干语句组成代码块
、函数名称
、参数列表
构成,它是组织代码的最小单元,使用函数能够完成必定的功能,在Python中函数主要分为三类:内置函数
、第三方函数库
、自定义函数
。经常使用的内置函数在前面已经介绍,第三方函数库须要先引入模块,经过模块调用,在模块学习中进行介绍,这里主要说的是如何自定义一个函数。学习
在Python中,定义一个函数要使用def语句,依次写出函数名
、括号
、括号中的参数和冒号:
,而后,在缩进块中编写函数体,函数的返回值用return语句
返回。下面是一个函数的基本结构ui
def 函数名(参数列表): 函数体(代码块) [return 返回值] # 函数能够无返回值
注意:3d
函数名
就是标识符
,命名要求同样语句块
必须缩进,约定4个空格
隐式会返回一个None
形参
定义: def abs(x): if x >= 0: return x else: return -x 调用: abs(-10)
上面只是一个函数的定义,j具体来看一下各个部分的解释:code
可调用对象
,函数名加括号
就表示调用。直接打印函数名,不会触发函数的执行,反而会打印函数的内存地址。orm
咱们自定义的函数abs,因为与内置函数重名,那么将会覆盖掉内置函数,因此请谨慎命名。对象
函数体内部的语句在执行时,一旦执行到return时,函数就执行完毕,并将结果返回。所以,函数内部经过条件判断和循环能够实现很是复杂的逻辑。若是没有return语句,函数执行完毕后会隐士的返回None
。若是咱们确实要return None
能够简写为return
,或者不写return语句(会让人看不懂,建议只写return)。
调用函数,那么只须要使用函数名加括号,就能执行,但若是函数定义了参数,那么必须在执行的时候传递参数给函授,不然会报异常!关于调用咱们还须要了解:
调用时写的参数是实际参数,是实实在在传入的值,简称实参
函数是可调用对象,可使用callable()进行判断
In [1]: def abs(x): ...: if x >= 1: ...: return x ...: else: ...: return -x In [2]: callable(abs) # 函数是可调用的,注意这里不能对函数加括号,那么callable判断的就是函数的返回值是否能够执行了 Out[2]: True In [3]: a = '123' In [4]: callable(a) # 字符串是不可调用的 Out[4]: False
定义函数的时候,括号中指定的就是函数的参数(形式参数),当咱们调用函数时,须要将数据进行传递,这种传递参数的方式就叫作传参,严格来讲函数只可使用两种方式:位置传参
和关键字传参
。
关键字传参:使用形参的名字来传入实参的方式
须要注意的时:参数传递时若是
使用
了形参的名字
,那么传入参数的顺序就能够
和定义的顺序不一样
,当位置传参和关键字传参混用时,位置传参必须放在关键字传参前面传入
。
定义函数function: In [1]: def function(x,y): ...: result = x + y ...: return result ...: 位置传参: In [2]: function(1,2) # 1对应x,2对应y。 Out[2]: 3 关键字传参: In [3]: function(y=1, x=2) # 使用关键字时,参数能够不用按照位置顺序。 Out[3]: 3 混合传参: In [8]: function(1, y = 3) # 混用时,关键字参数必需要再位置参数右边 Out[8]: 4
在定义形式参数时,为参数指定对应的值,就叫作参数的默认值,当定义了参数的默认值之后,咱们传参时能够选择传递该参数的值,也能够选择不传递,当不传递
此参数的值时,该参数就使用指定的默认值
,不然
将会使用传递的值
。
参数默认值也属于位置参数,只不过是给位置参数定义了默认值。
In [9]: def function(x = 10, y = 20): ...: return x + y ...: In [10]: function(2) # 2会以位置参数的形式传递给x,y没有传递,会使用默认值 Out[10]: 22 In [11]: function(y=100) # x没有传递,会使用默认值 Out[11]: 110 In [12]: function(x=100) # y没有传递,会使用默认值 Out[12]: 120 In [13]: function(20, y=500) # 20以位置参数的形式传递给x,500以关键字参数的形式传递给了y Out[13]: 520
当定义参数的默认值时,注意
默认值参数
必需要放在位置参数的右边
In [1]: def functions(x=1, y): # 必须把x=1,放在y的右边,不然没法完成函数定义 ...: print(x+y) File "<ipython-input-1-ea496fa7fc81>", line 1 def functions(x=1, y): ^ SyntaxError: non-default argument follows default argument
使用默认值参数的好处是:
可变参数顾名思义表示参数的数量是可变的,而且可使用一个形参匹配任意个实参。针对传递参数方式的不一样又分为可变位置传参
和可变关键字传参
。
在形参前使用*
号,表示该形参是可变参数,能够接受多个实参,在函数内部,可变参数会封装成元祖(即使是没有传递)
In [15]: def function(*nums): ...: print(nums) ...: In [16]: function(1,2,3,4) # 多个参数会被nums收集 (1, 2, 3, 4) In [18]: function([1,2,3,4]) # 会把list收集成元祖类型 ([1, 2, 3, 4],)
在函数定义时,通常的规范是使用
*args
, 表示收集多个位置传参。
在形参前使用**
号,表示该形参是可变关键字参数,能够接受多个关键字参数,在函数内部,可变关键字参数会封装成字典(即使是没有传递)
In [20]: def function(**kwargs): ...: print(kwargs) ...: In [21]: function(a=1,b=2) {'a': 1, 'b': 2} # 参数的默认值和位置参数同时使用 In [5]: def function(x=1,y=2,**kwargs): ...: print('x = {}'.format(x)) ...: print('y = {}'.format(y)) ...: print(kwargs) ...: In [6]: function(a=10,b=20) # 参数没有a,b形参,则被kwargs接收 x = 1 y = 2 {'a': 10, 'b': 20} In [7]: function(x=100,y=200,z=300) # z没有被匹配,被kwargs接收 x = 100 y = 200 {'z': 300} In [8]: function(1000,2000,z=300) # 前面的按照位置参数赋值,z一样被字典kwargs收集 x = 1000 y = 2000 {'z': 300} In [9]:
前面说的各类参数是能够混合使用的,当混合使用时遵循必定的顺序,简单总结一下,按照从左至右的顺序来讲:位置参数,默认值参数,可变位置参数,可变关键字参数:def function(位置参数,默认值参数,可变位置参数,可变关键字参数)
。
不管如何,
顺序不能颠倒
。
In [9]: def function(x,y,z=1,*args,**kwargs): # x,y,z都为位置参数,z的默认值为1,*args收集额外的位置传参,kwargs收集额外的关键字传参 ...: print(x,y,z) ...: print(args) ...: print(kwargs) ...: In [10]: function(1,2,3,4,5,a=1,b=2) 1 2 3 (4, 5) {'a': 1, 'b': 2}
针对可变参数以及不一样的混用方式能够有以下结论:
位置可变参数
和关键字可变参数
一个星号*
两个星号**
可变位置参数
收集造成一个tuple
,可变关键字参数
收集造成一个dict
混合使用参数的时候,在定义阶段要遵循以下顺序:位置参数
,默认值参数
,可变位置参数
,可变关键字参数
当位置传参和关键字传参同时使用时,
不能够重复赋值!
,这一点使用的时候很重要。
Python3的函数参数中,新增了keyword-only参数,什么叫keyword-only参数?咱们说当在一个星号参数(可变位置参数)后,出现的普通参数,咱们称它为keyword-only参数,由于多余的位置参数都会被*args收集,只能经过keyword的方式对这些形参进行赋值
,因此它们只能使用'关键字传参'。
In [11]: def function(a,b,c=1,*args,x,y=2,**kwargs): # x,y是keyword-only参数,其中y存在默认值,能够不用传递,x必须使用关键字的方式进行传递 ...: print(a,b,c) ...: print(args) ...: print(x,y) ...: print(kwargs) ...: In [12]: function(100,200,300,400,d=100,e=200) --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-12-cf60009e3d1f> in <module> ----> 1 function(100,200,300,400,d=100,e=200) TypeError: function() missing 1 required keyword-only argument: 'x' In [13]: function(100,200,300,400,d=100,e=200,x=500) 100 200 300 (400,) 500 2 {'d': 100, 'e': 200}
特殊形式:
In [17]: def function(*,x,y): ...: print(x,y) ...: In [18]: function(1,2,3,x=100,y=200) --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-18-7d07ae79c088> in <module> ----> 1 function(1,2,3,x=100,y=200) TypeError: function() takes 0 positional arguments but 3 positional arguments (and 2 keyword-only arguments) were given In [20]: function(x=100,y=200) 100 200
这里*表示不接受位置传参,只能使用关键字对参数进行赋值
注意:使用了keyword-only参数,那么在定义形参的时的顺序就有所改变了,它们是:位置参数,默认值参数,可变位置参数,keyword-only参数,可变关键字参数
前面咱们说过Python的封装与结构,这里的参数也能够利用这种思想进行结构,现有以下函数:
In [21]: def add(x=1,y=2): ...: print(x+y) ...: In [22]: t = (10,20) In [23]: add(t[0],t[1]) # 将元祖的元素1和元素2分别传给X,y 30 In [24]: add(*t) 30 In [25]: d = {'x':100, 'y':200} In [30]: add(**d) 300
10,20
,做为位置传参
传递给add函数x=100,y=200
,做为关键字传参
传递给函数如今再来回头看一下,什么时参数解构?
*解构成位置参数
**解构成关键字参数
In [31]: def add(a,b,*args,m,n,**kwargs): ...: print(a+b+m+n) ...: In [32]: dic = {'a':100,'b':200} In [33]: add(**dic,m=300,n=400,x=1000) 1000
咱们一般编写函数除了代码能够复用,更多的时候须要的是知道函数的运算结果,那么函数把运算的结果返回给咱们,这个结果就叫做作函数的返回值。使用return
关键字进行返回。
# 返回1个数据 In [34]: def add(x,y): ...: result = x + y ...: return result ...: In [35]: a = add(10,20) In [36]: print(a) 30 # 返回多个数据 In [37]: def add(x,y): ...: result = x + y ...: test = x * y ...: return result,test ...: In [38]: a = add(10,20) In [39]: print(a) (30, 200) # 多个return语句 In [40]: def add(x,y): ...: if x > 10: ...: return y ...: else: ...: return x ...: In [41]: a = add(10,20) In [42]: print(a) 10
总结:
return能够理解为,结束当前函数计算,返回值!
多个返回值会被包装成一个tuple进行返回,因此函数永远只能返回一个数据。