# 函数
# 定义函数
一个任务:把每个值乘 2 次方并除以 5 再加一
你可以这样做:a = 10
a = a**2/5+1
print(a)
但假如你要在不同的地方做 x 次操作呢?
就可以用到函数了:def demo(num):
return num ** 2 / 5 + 1
a = demo(10)
print(a)
以下是函数的语法:def 函数名(形参):
代码
return
后面是函数的返回值,需要使用变量 "接住"
在遇到 return
关键字之后,函数会自动退出
return 不是必须的,没有 return 则会在函数执行完后退出
# 参数
参数分为形参和实参,定义时的叫形参,填入的是实参
# 标准参数和类型标注
def demo(num:int|float) -> float: | |
return num+1 |
num
是标准参数,不填会报错: TypeError: demo() missing 1 required positional argument: 'num'
表示多个类型,则有多种标注方法:
- 3.9 版本以上:
int|float
,|
符号代表 A 类型或 B 类型 - Union [int, float], 需要先导入
typing
模块
-> float
表示返回值是float
类型,方便 IDE 分析
类型标注和返回值标注不是必须的,但建议使用
# 缺省形参和特殊参数
def demo(num: int | float = 10) -> float: | |
return num ** 2 / 5 + 1 | |
a = demo() | |
print(a) |
num: int | float = 10
中的 = 10
表示缺省
如果没有填入参数就使用 10 作为参数输入def demo(*args):
for i in args:
print(i)
demo(1,2,3)
这个函数会将传入的所有元素输出
*args
表示不知道会输入多少个元素,把所有参数做成元组处理def demo(**kwargs):
for k,v in kwargs.items():
print(k,v)
demo(k1=10,k2=12)
**kwargs
代表把传入的参数作为字典处理,因此传入必须使用 键=值
这种方法
看不懂 **kwargs.items()
是什么意思就去复习一下字典
# 函数名
函数名和变量的命名规则很像,但可以使用小驼峰命名法:
例:numOutput
首字母小写,剩下的单词开头大写
# 作用域
python 的作用域分为以下几种:
Local 局部作用域,简写为 L
Enclosing 闭包作用域,简写为 E
Global 全局作用域,简写为 G
Built-in 内置作用域,简写为 B
变量和函数的搜寻的顺序:L->E->G->Bgvar = 0 # 全局作用域
def demo():
evar = 1 # 对于 demo2 的闭包作用域,对于 demo 的局部作用域
def demo2():
lvar = 2 #局部作用域
在作用域外不能调用作用域内的变量与函数gvar = 0 # 全局作用域
def demo():
evar = 1 # 对于 demo2 的闭包作用域,对于 demo 的局部作用域
def demo2():
lvar = 2 #局部作用域
demo2()
# NameError: name 'demo2' is not defined. Did you mean: 'demo'?
把 demo2 套在 demo 里就叫闭包函数
加入作用域内有同名变量或更改变量值,需要使用 global
和 nonlocal
声明变量
语法: nonlocal/global 变量
global 是全局变量,nonlocal 是闭包变量
# typing 模块
typing 模块是 python 内置的类型表示模块,对于函数类型标注非常有帮助
# 可迭代容器数据
举个例子,这个函数可以遍历可迭代容器数据并输出:def printSeq(seq: list):
for i in seq:
print(i)
最开始使用 list 进行类型标注,但假如要使用元祖,python 就会报错。
而且如果只是单纯加上元祖,后续出现新的类型还需要改代码
这个时候就可以用到 list 的抽象类 typing.Sequence
def printSeq(seq: typing.Sequence):
for i in seq:
print(i)
就可以实现接受所有的可迭代容器数据
# 可能为 None 的参数
在实际开发中,部分参数需要传入 None 来实现功能,虽然可以用 |
或 Union
来解决,但有更优雅的方法:def numAbs(n: int, mode: typing.Optional[bool]):
if mode is None:
return 0
else:
return abs(n)
typing.Optional
与 Union
是等价的,只是前者默认包含 None
typing 包含有大量抽象类供类型标注,可以查看官方文档
typing 中部分内置类 (区别为首字母大写) 不要使用,请使用标准的内置类
这些冗余的类会在 python3.9 发行五年后的第一个版本移除