python学习之路(四) ---函数
* 函数有关文章
一.函数的作用
当我们在写一个复杂的程序的时候,可以能会在很多地方上用到相同的功能,写起来代码量非常大,通过函数可以解决大量的代码冗余,我们只需要将各个功能封装到一个函数内,需要的时候就调用这个函数就可以,这样写起来的代码可读性也得到很大的提升,而且当我们后续需要增添新功能的时候也非常的方便,维护起来更加的方便.
二.内置函数和自定义函数
- 内置函数
python中为我们提供的许多的内置函数,可以到https://www.runoob.com/python/python-built-in-functions.html去查看.
- 自定义函数
def 函数名(参数1,参数2,参数3,...): '''注释''' 函数体 return 返回的值
函数名 : 函数的名字要反映一个函数的功能,函数的名字不能和python中的关键字一样,在python我一般会去下划线结合的名字,如: def hello_world():,当然驼峰式也可以.
参数 : 参数可以没有,会详细讲到参数
注释 : 在注释中我们可以大致讲一下函数的功能以及参数的含义和返回值的含义,方便以后阅读时更加的清晰和易于维护
函数体 : 函数体里面就是我们要实现的功能的逻辑代码了
返回值 : 当没有return时,函数的返回值默认为None
三.函数的参数
- 形参和实参
函数的形参即为变量名,而实参就是具体的变量值
def add(x, y): """ 这是一个加减运算的函数 :param x: 第一个数 :param y: 第二个数 :return: 运算的结果 """ result = x + y return result res = add(1, 2)
print(res)
其中x,y就是形参,而1, 2 就是实参
- 位置参数 : 按照从左到右定义参数
位置形参:必须传值给形参
位置实参:按照位置给形参传值,一一对应
def func(name, country): result = "%s爱%s" % (name, country) return result res = func("我", "中国", "日本") print(res)
""" TypeError: func() takes 2 positional arguments but 3 were given
"""
- 关键字参数 : 实参按照key = value 的方式传值
使用关键字参数时无需按照位置来传参,但是需要注意的是,当同时存在未知参数和关键字参数时,未知参数一定要在关键字参数的前面,而且不能对一个形参赋多次值
def func(name, country): result = "%s爱%s" % (name, country) return result res = func(country = '中国', "我")# 关键字参数在未知参数前面 print(res) """ SyntaxError: positional argument follows keyword argument """
def func(name, country,city): result = "%s爱%s%s" % (name, country,city) return result res = func("我", city="湛江",country="中国",name="你")# 对名字赋值了两次 print(res) """ 'TypeError: func() got multiple values for argument 'name' """
- 默认参数
默认参数是在定义函数式就已经给形参赋值,目的是方便一些不怎么需要变化的的参数在传递实参不需要再赋值.,默认参数通常设为不可变类型,默认参数要放在非默认参数的后面,否则会报错.
def func(name, city, country="中国"): result = "%s爱%s%s" % (name, country, city) return result res = func("我", city="湛江") print(res) """" 我爱中国湛江 """" def func(name, city, country="中国"): result = "%s爱%s%s" % (name, country, city) return result res = func("我", city="湛江", country="九州") print(res) """" 我爱九州湛江 """"
- 可变长参数
可变长参数是指实参的函数不确定,需要用特殊的参数来接收溢出的实参,具体有*args和**kwargs两种
(1) *args ----可变长度的位置参数,存放在一个元组中
def func(x, y, *args): print(x, y) print(args) print(type(args)) func(1, 2, 3, 4, 5) """" 1 2 (3, 4, 5) <class 'tuple'> """"
我们也可以在传递实参时通过*来解析一个列表或元组,
def func(x, y, *args): print(x, y) print(args) print(type(args)) func(1, 2, *(3, 4, 5))# *号必须加上,否则会将整个元组作为一个实参 """" 1 2 (3, 4, 5) <class 'tuple'> """"
(2) *kwargs ----可变长度的关键字参数,以键值对的形式存放在字典中
def func(x, y, **kwargs): print(x, y) print("kwargs : ", kwargs) print(type(kwargs)) func(1, y=2, z=3, g=4) """" 1 2 kwargs : {'z': 3, 'g': 4} <class 'dict'> """"
同样我们也可以在传递实参时通过**来解析一个字典
def func(x, y, **kwargs): print(x, y) print("kwargs : ", kwargs) print(type(kwargs)) func(1, y=2, **{'z': 3, 'g': 4})
- 命名关键字参数
*后定义的参数,必须被传值(有默认值的除外),且必须按照关键字实参的形式传递,这样可以保证,传入的参数中一定包含某些关键字
def func(x, y, *, a=1, b, **kwargs): print("x,y : ", x, y) print("a : ", a) print("b : ", b) print("kwargs : ", kwargs) func(1, 2, b=3) """" x,y : 1 2 a : 1 b : 3 kwargs : {} """"