函数就是包裹一部分的代码,实现某一个功能,达成某一个目的,而且当这段代码如果使用或者重复使用的时候,只需要很简单的调用即可,大大减少了代码的维护难度。
函数的特点可以反复调用,提高代码的复用性,提升开发效率,便于维护管理。
函数的定义和调用函数的定义要使用到关键字def
,且函数定义不会执行函数中的代码,而是需要调用函数才会执行。
定义函数在关键字def
后面加上函数名,然后后面加上括号,括号中可以酌情选择是否写上参数,在对应的作用域中写上代码。
# 语法:
def function_name([parameter0],[parameter1]):
code0
code1
code2
……
调用方法
直接使用定义好的函数的函数名加上括号,括号中写上对应的参数,就会执行作用域中的代码。
# 语法:
funciton_name([parameter0],[parameter1])
注意,只要函数只有在调用的时候才能执行其中的代码
定义一个没有参数的函数
# 定义函数
def func():
print('this is function')
# 调用函数
func() # this is function
带有参数的函数
# 定义函数
def func(name):
print('this is ' + name)
# 调用函数
func('msr20666') # this is msr20666
命名
函数的命名和变量命名的规则是一样的,推荐使用小驼峰命名法。
参数函数的参数,是配合函数运算的值。在函数中的代码使用参数的时候,就和使用变量的方法是一样的。
定义函数的时候的参数叫做形式参数,形参就就相当于定义变量的变量名,填的参数只是为了确定功能,所以叫作形式参数;调用函数的时候的参数叫做实际参数,实参就相当于定义变量的时候的值,这个时候的参数具有实际的作用,所以叫作实际参数。
参数的分类函数调用的时候的参数要和定义的时候一一对应。
普通形参和普通实参普通形参就是定义函数时在括号内直接写参数名,普通形参没有赋予值,所以在函数调用的时候必须要对普通形参赋予值,否则报错。
调用函数的时候直接写上的值就是普通实参。
# 直接写上参数名就是普通形参
def myName(name):
res = 'My name is %s' % name
print(res)
my_name = 'msr'
# 调用函数的时候直接写上的值就是普通实参
myName(my_name)
# 参数要一一对应,所以调用函数的时候不写参数就会报错
myName() # error
默认形参
默认形参就是在定义函数的时候,参数就指定了一个值,换句话说默认形参就是一个带有默认值的普通形参。在调用函数的时候如果给默认参数指定了值,默认参数的实际值就是调用处的值,如果没有赋予值,默认参数的值就是定义处的值。
# 定义函数的时候带有默认值的就是默认参数
def myName(name='msr'):
res = 'My name is %s' % name
print(res)
# 调用处指定值
my_name = 'msr20666'
myName(my_name) # My name is msr20666
# 调用处不指定值
myName() # My name is msr
当普通参数和默认参数他同时存在的时候,默认参数必须要在普通参数的后面,否则报错。
def myName(name, name1='msr'):
print(name, name1)
myName('wxd',) # wxd msr
关键字实参
普通实参就是在调用函数的时候直接填写值,这样的赋值不能打乱顺序,要按照形参定义的顺序来写。
关键字实参是对具体的某个参数赋值,这样就可以打乱参数的顺序使用,但是全部使用关键字实参必须将所有普通形参全部使用关键字实参,否则报错
def name(name1, name2, name3, name4='没有名字'):
print(name1, name2, name3, name4)
# 普通实参
name(111, 222, 333, 444) # 111 222 333 444
# 关键字实参
name(name2=444, name1=222, name3=111, name4=333) # 222 444 111 333
普通实参和关键字实参一起使用的时候,关键字实参也是不能写在普通实参的前面的。
注意要区分默认形参和关键字实参,默认形参和关键字实参在语法上是一模一样的,都是给某个参数一个固定的值,且都必须跟在普通形参和实参之后。但是区分的方法很简单,默认形参是形式参数,在定义函数时的就是默认形参,关键字实参是实际参数,在调用函数时的就是关键字实参。
普通收集参数函数的实参要和形参一一对应,如果有普通实参没有对应的形参,普通收集参数就可以用来专门收集多余的普通实参,在普通形参的前面加上一个*
就是普通收集参数,普通收集参数一般习惯命名为 args
。收集的数据会变成一个元组。
def func(name, *args):
print(name) # msr
print(args) # (1, 2, 3, 4, 5, 6)
func('msr', 1, 2, 3, 4, 5, 6)
关键字收集参数
关键字收集参数和普通收集参数的作用和普通收集参数的租用基本相同的,只不过关键字收集参数收集的是关键字实参,关键字收集参数在普通形参的前面加上 **
符号,一般命名为kwargs
,收集的数据变成一个字典。
def func(*args, **kwargs):
print(args)
print(kwargs)
func(1, 2, 3, 4, name='msr', age=18, sex=0)
'''
结果:
(1, 2, 3, 4)
{'name': 'msr', 'age': 18, 'sex': 0}
'''
普通收集参数和关键字参数一起可以收集所有的实参
# 收集所有的实参
def func(*args, **kwargs):
print(args)
print(kwargs)
命名关键字参数
命名关键字参数就是在函数调用的时候,必须使用关键字实参进行赋值的形参。
定义命名关键字参数的两种方式:
def function_name(parameter, *, parameter2)参数2是命名关键字, * 后面的参数为命名关键字
**def function_name(*args, parameter, kwargs)
parameter是命名关键字,普通收集参数后面的普通形参是命名关键字参数
# 方法一, * 本身不是一个参数:
def func(*, a, b, c, d):
print(a, b, c, d) # A B C D
func(a='A', b='B', c='C', d='D')
# 方法二:
def func(*args, a, b, c):
print(a, b, c) # 3 4 2
func(a=3, b=4, c=2)
符号 * 和 ** 的使用
* 和 ** 在函数的定义处,用来做收集操作,打包
* 和 ** 在函数的调用处,用来做打散操作,解包
* 在定义处用来收集普通实参,成为元组;在调用处用来打散容器成为普通实参,如果是字典,只获取键。
** 在定义处用来收集关键字实参,成为字典;在调用处用来打散字典(只能是字典,且键为字符串)成为关键字实参。
def func(*args):
print(args)
lst = [1, 2, 3, 4, 5, 6]
# 如果将列表直接作为参数放入,lst就是一个参数
func(lst) # ([1, 2, 3, 4, 5, 6],)
# 如果在lst前面加上 * ,就将列表列表解包,每一个元素都是一个参数
func(*lst) # (1, 2, 3, 4, 5, 6)
相当于将列表中的元素一个个拿出,当成一个个普通实参给函数进行调用,**也是一样的。
def func(**kwargs):
print(kwargs)
dct = {'one': 1, 'two': 2, 'three': 3}
# ** 可以解包字典
func(**dct) # {'one': 1, 'two': 2, 'three': 3}
return关键字
return可以返回自定义函数的值,叫做返回值,可以把函数最终运算出的结果返回到函数的调用处。
- return可以返回任何的python数据,六大数据类型、对象、类、函数……,只需要将要返回值的写在return的后面即可;
- 定义return返回值返回的就是定义的值,返回返回None;
- 函数在执行到return的时候跳出函数,函数中剩余的代码不会在执行;
不指定return返回值,返回None。
# 定义函数
def func():
print('hello')
# 调用函数
# 函数执行打印'hello',没有定义返回值,返回None给res
res = func()
print(res)
'''
结果:
hello
None
'''
定义返回值。
# 定义函数
def func():
print('hello')
return 'motherland'
# 调用函数,返回'motherland'给res
res = func()
print(res)
'''
结果:
hello
motherland
'''
执行return之后,函数后面未执行的代码不再执行。
# 定义函数
def func():
print(1)
return 2
print(3)
# 调用函数
func()
'''
结果:
1
'''
函数名的使用
python中的函数可以像变量一样,动态创建销毁,当作参数传递,作为值返回,叫第一类对象,其他语言功能有限。
-
函数名是一个特殊的变量,可以作为变量使用和赋值;
def func(): print('hello motherland') var = func var() # hello motherland
-
函数可以像变量一样销毁
def func(): print('hello motherland') del func func() # error,不存在
-
函数名可以作为容器类型数据的元素;
def func0(): print('func 0') def func1(): print('func 1') def func2(): print('func 2') lst = [func0, func1, func2] for i in lst: i() ''' 结果: func 0 func 1 func 2 '''
-
函数名可以作为函数的参数;
def func1(): print('我是 func 1') def func2(function): function() func2(func1) # 我是 func 1
-
函数名可以作为函数的返回值;
def func1(): print('我是 func 1') def func2(function): return function res = func2(func1) res() # 我是 func 1
在定义函数的时候,在函数的上方使用单行注释、或者在下方使用多行注释可以为函数注释说明。
可以使用__doc__
方法或者是help
函数查看。
使用help
函数查看在函数的注释说明。
# 这是我的第一个函数
# 函数的注释在上方
def func():
pass
print(help(func))
'''
结果:
Help on function func in module __main__:
func()
# 这是我的第一个函数
# 函数的注释在上方
None
'''
使用 __doc__
方法查看。
def func():
"""
这是我的第二个函数
函数的注释在下方
"""
pass
# 使用
print(func.__doc__)
'''
结果:
这是我的第二个函数
函数的注释在下方
'''
总结
形参在一起使用的时候要哪找顺序。
普通参数 -> 默认参数 -> 普通收集参数 -> 命名关键字参数 -> 关键字收集参数