什么是函数?数学中有函数的概念,用于完成一个计算功能。python中的函数也是用于完成功能,并且不局限于计算,将你想实现的功能封装起来,用特定的语法定义,就成为了一个函数。使用函数可以避免函数冗长,拓展性和可读性差的缺点。
1、函数定义和调用
定义与调用函数有固定的格式
# 定义 def func(): print('hello,world') # 调用 func()
def add2(x, y): print(x + y) return "add2函数执行" # 调用 add2(1, 2)
def register(): pass # 用于保持结构的完整
在函数定义阶段,只检测语法错误,不执行代码;函数调用时,才会执行代码内容。
函数的调用除了直接调用外,还有 放在表达式里,将函数执行结果二次加工;作为参数,传给另外的函数(函数嵌套调用)。
其中,将函数执行结果二次加工,也可以在定义函数时,将想要的结果返回(return),然后对返回值进行处理。
•. 返回的值没有类型限制,也没有个数限制
I: return或者函数没return:返回值None
II: return 值:返回的就是该值本身
III: return 值1,值2,值3:返回元组(值1,值2,值3)
def square(x): res = x ** 2 return x, res square(5) # 这是函数的返回值,此时没有输出(打印),可以将其赋给变量后使用 print(square(5)) # 输出 (5, 25)
3、函数的参数
在上面的函数里,我们用到了参数,在定义阶段的参数(形参),可以看作变量名,在调用阶段的参数(实参),就是给变量名赋值,即将值绑定到变量名,这种绑定关系在函数结束后接触。
形参分为 位置形参和默认形参。
实参分为 位置实参和关键字实参。
def func(x, y, z): print(x, y, z) func(1, 2, 3)
x,y,z是位置形参,与之对应的在调用阶段的1,2,3就是位置实参。这两者一一对应,按从左到右的顺序,只要有位置形参,就必须有位置实参。
def func(x, y=2): print(x, y) func(1)
y = 2 是默认形参,它给y指定了一个默认值,如果调用阶段没有对y传值,y默认为2。
它的用途是,在调用过程中,如果某个参数的值出现多次相同,就可以将其指定为默认参数。
注意:位置形参必须放在默认形参的前面
def func(x, y, z): print(x, y, z) func(1, z=3, y=2)
调用阶段指定的 z = 3, y = 2 是关键字实参,它按照key = vaule的形式,写在位置实参的右边。由于指定了key,故可以不按照定义时形参的顺序,但一定是在位置是参的右边。
4、参数中*和**的用法
由于形参与实参是一一对应的关系,如果需要传入的参数个数可变,就需要从函数定义时改变参数的个数,为了能让参数个数更加灵活,python提供了可变长参数。
• *形参:*会将溢出的位置实参存成元组的形式然后赋值其后变量名,习惯上使用*args接收调用时传的位置实参
def func(x, y, *args): print(x, y, args) func(1, 2, 3, 4, 5, 6) # 输出 1 2 (3, 4, 5, 6)
• **形参:**会将溢出的关键字实参存成字典的格式然后赋值其后变量名,习惯上使用**kwargs接收调用时传的关键字实参
def func(x, y, **kwargs): print(x, y, kwargs) func(1, y=2, z=3, m=1, n=2) # 输出 1 2 {'z': 3, 'm': 1, 'n': 2}
• *实参:先将实参打散成位置实参,然后再与形参做对应,*后必须是可迭代对象。
def func(x, y, z): print(x, y, z) func(1, *[2, 3]) # 输出1 2 3 func(*[1, 2, 3]) # 输出1 2 3
• **实参:先将实参打散成关键字实参,然后再与形参做对应,**后是字典。
def func(x, y, z): print(x, y, z) func(**{'x': 1, 'z': 3, 'y': 2})
可变长参数给我们提供了一种帅到不行的传值方式,即:
def inner(x, y, z): print(x, y, z) def doco(*args, **kwargs): inner(*args, **kwargs) doco(1, 2, 3) # 输出 1 2 3
你会发现,在dico() 里传入的参数,被传入了inner() 函数,这种传值方法在讲到装饰器时,你会体会到它有多帅!
阶段思维导图