目录
1. 函数形式
定义函数使用关键字 def,后跟函数名与括号内的形参列表;
函数语句从下一行开始,并且必须缩进;
函数没有函数语句会报错,此时对于没有具体执行的函数,可以使用pass语句直接跳过。
pass 语句不执行任何操作。语法上需要一个语句,但程序不实际执行任何动作时,可以使用该语句。
def myfuction():
... print('Hello,world!')
...
myfuction()
Hello,world!
#使用pass语句,函数执行直接通过
def myfuction():
... pass
...
myfuction()
2. 形参和实参
函数定义时,函数名后括号内的为:形式参数,简称形参;
函数调用时,函数名后括号内的为:实际参数,简称实参;
形参用于在函数内部声明变量,实参则是调用函数时给予形参的实际赋值;
官方文档:
函数在 执行 时使用函数局部变量符号表,所有函数变量赋值都存在局部符号表中;
引用变量时,首先,在局部符号表里查找变量,然后,是外层函数局部符号表,再是全局符号表,最后是内置名称符号表。
因此,尽管可以引用全局变量和外层函数的变量,但最好不要在函数内直接赋值(除非是 global 语句定义的全局变量,或 nonlocal 语句定义的外层函数变量)。
#x1、x2即形参
def myfuction(x1,x2):
... print(f'Hello,{x1}! Hello,{x2}!')
...
#'Dave'、'Tom'即实参
myfuction('Dave','Tom')
Hello,Dave! Hello,Tom!
3. 函数返回值
函数通过return语句返回值 ;
return 语句,在语法上只出现于函数定义所嵌套的代码,不会出现于类定义所嵌套的代码;
如果提供了表达式列表,它将被求值,否则以 None 替代;
return 会离开当前函数调用,并以表达式列表 (或 None) 作为返回值。
函数中有多个return语句的情况,任一return语句执行后,函数终止,后续return语句不再执行;
函数可以一次性返回多个值,默认以元组形式打包,也可以打包返回列表、字典等。
#多个return语句,只有第一个return返回数据'abc'成功
def myfuction():
... return 'abc'
... return '123'
...
myfuction()
'abc'
#即使return返回None,也会终止函数
def myfuction():
... return None
... return '123'
...
myfuction()
#return可以返回字典、集合、序列等类型
def myfuction(type):
... if type == 1: return 123.4-56789j
... if type == 2: return 'abc123& ^'
... if type == 3: return [1,'23',[4,(5,6)]]
... if type == 4: return (['abc',0],1,('2',3))
... if type == 5: return {'a':1,2:'b',3:[1,'a',{5,6,7}]}
... if type == 6: return {'a',1,2,3}
...
myfuction(1)
(123.4-56789j)
myfuction(2)
'abc123& ^'
myfuction(3)
[1, '23', [4, (5, 6)]]
myfuction(4)
(['abc', 0], 1, ('2', 3))
myfuction(5)
{'a': 1, 2: 'b', 3: [1, 'a', {5, 6, 7}]}
myfuction(6)
{1, 2, 3, 'a'}
#函数可以一次性返回多个值,默认以元组形式打包
def functionx():
... return 1,'a',[0,(1,2)]
...
functionx()
(1, 'a', [0, (1, 2)])
#函数也可以打包返回列表、字典等
def functionx():
... return [1,'a',[0,(1,2)]]
...
functionx()
[1, 'a', [0, (1, 2)]]
def functionx():
... return {1:'a',2:'b'}
...
functionx()
{1: 'a', 2: 'b'}
4. 函数文档
函数文档,也就是函数的说明书,只需使用字符串(三引号多行字符串:"""xxx""")即可创建;
函数文档写在函数最顶部,函数主体之前,如果在函数文档之前有可执行代码,则函数文档只是普通注释,无法通过特殊属性__doc__获取;
函数文档,可使用help()函数进行查看,也可以通过特殊属性__doc__获取。
#函数文档
def functionx():
... """
... 我有一个想法!
... 写一个空函数!
... """
... pass
#函数文档也可以通过help()函数读取
print(functionx.__doc__)
我有一个想法!
写一个空函数!
def functionx():
... """
... 我有一个想法!
... 写一个空函数!
... """
... pass
...
help(functionx)
Help on function functionx in module __main__:
functionx()
我有一个想法!
写一个空函数!
#注释前有可执行代码,不再是函数文档
def functionx():
... pass
... """
... 我有一个想法!
... 写一个空函数!
... """
...
print(functionx.__doc__)
None
5. 类型注释
5.1 基础格式
类型注释,是函数作者为函数参数类型及返回值类型写的提示,格式如下:
def function(arg1:arg1type,arg2:arg2type...) -> returntype:
argtype、returntype效果类似注释,给予编码者理解函数,不影响函数执行;
如违反类型注释,不报错,可以继续执行;
类型注释填写非数据类型的其他内容,报错。
def funx(var1:int,var2:str) -> str:
... return f'{var1},{var2}'
...
#按类型注释录入实参,执行成功
funx(1,'2')
'1,2'
#违反类型注释,不报错,可以继续执行;
funx('a',0)
'a,0'
#类型注释填写非数据类型的其他内容,报错
def funx(var1:intx,var2:str12) -> str:
... return f'{var1},{var2}'
...
Traceback (most recent call last):
File "<input>", line 1, in <module>
NameError: name 'intx' is not defined
def funx(var1:int,var2:str) -> str123:
... return f'{var1},{var2}'
...
Traceback (most recent call last):
File "<input>", line 1, in <module>
NameError: name 'str123' is not defined
5.2 默认参数类型注释
默认参数做类型注释,格式如下:
def function(arg1:arg1type = default1,arg2:arg2type = default2...) -> returntype:
即正常在类型注释后,给相应形参赋值默认参数。
def funx(var1:int = 0,var2:str = 'ABC') -> str:
... return f'{var1},{var2}'
...
funx()
'0,ABC'
funx('2',1)
'2,1
5.3 序列映射类型注释
对序列、映射内部元素类型一致的形参,可以对形参内部元素做类型注释,如下:
def function(var1:iterable[argtype],var2:dic[keytype,valuetype]...) -> returntype:
还可以对元素的元素做类型注释,如下函数中的字典类型的value注释为列表类型,列表的元素注释为int类型;
多层级、复杂的类型注释一样是作为注释存在,不按注释录入实参,仍可正常执行。
#按类型注释录入实参,执行成功
def funx(var1:list[int],var2:dict[str:list[int]]) -> list:
... for i in var2:
... var1 += (var2[i])
... return var1
...
funx([1,2,3],{1:[4,5],2:[6,7]})
[1, 2, 3, 4, 5, 6, 7]
#不按类型注释录入实参,执行成功
def funx(var1:str,var2:dict[str:list[int]]) -> list:
... for i in var2:
... var1 += i
... return var1
...
funx(1,(2,3,4,5))
15
5.4 第三方模块类型检测
还可以使用第三方模块,如 Mypy 等真正做一下类型检测,简单示例如下:
编写代码如下图:
按如下路径启动mypy:
或者右键点击待检查代码文件:
返回检查结果:
6. 内省
内省,也叫自省,是程序运行时进行自我检测的机制,通过一些特殊的属性来实现,当前常用函数属性如下:
- __name__:获取函数名
- __annotations__:获取类型注释
- __doc__获取函数文档
- __defaluts__:获取函数各参数默认值
- __code__:获取函数代码位置
def functiontest(var1:str,var2:list[int]) -> str:
... """
... 函数测试
... :param var1: 初始字符串
... :param var2: 整型列表
... :return: 整合后的列表
... """
... for i in var2:
... var1 += str(i)
... return var1
...
#读取函数名称
functiontest.__name__
'functiontest'
#读取函数文档,通过 print() 函数可读性更好
functiontest.__doc__
'\n 函数测试\n :param var1: 初始字符串 \n :param var2: 整型列表\n :return: 整合后的列表\n '
print(functiontest.__doc__)
函数测试
:param var1: 初始字符串
:param var2: 整型列表
:return: 整合后的列表
#读取类型注释
functiontest.__annotations__
{'var1': <class 'str'>, 'var2': list[int], 'return': <class 'str'>}
import easygui
#获取函数各参数默认值
print(easygui.boolbox.__defaults__)
('Shall I continue?', ' ', ('[T]rue', '[F]alse'), None, '[T]rue', '[F]alse')
#获取函数代码位置
print(easygui.boolbox.__code__)
<code object boolbox at 0x000001FDA7E037C0, file "D:\Anaconda\lib\easygui\boxes\derived_boxes.py", line 103>