def 定义函数
def 语句是定义函数的语句。语法如下:
@assignment_expression
def funcname(parameter_list) -> expression:
suite
其中的装饰器 @assignment_expression
,形参 parameter_list
和标注 -> expression
是可选项。
函数定义是一条可执行语句。它执行时会将函数名称 funcname
绑定到一个函数对象(函数可执行代码的包装器)。
例如,用必选项定义一个什么也不做的函数如下:
def f():
pass
f
<function __main__.f()>
一个函数定义可以被一个或多个装饰器表达式所包装。
装饰器必须是可调用对象,它会以该函数对象作为唯一参数被发起调用。
其返回值将被绑定到函数名称。多个装饰器会以嵌套方式被应用。
@str
@type
def f():pass
f
"<class 'function'>"
大致相当于:
def f():pass
f = str(type(f))
f
"<class 'function'>"
函数形参 parameter_list
详见 函数形参。
函数标注 -> expression
可以是任何表达式,标注对提高代码的可读性非常有用,看标注而不需要看代码上下文就大概知道代码的使用。例如:
# 标注函数的参数和返回值类型
def f(arg:int) -> list:
return list(str(arg))
f(123)
['1', '2', '3']
return 语句
return 在语法上只会出现于函数定义所嵌套的代码,不会出现于类定义所嵌套的代码。
如果提供了表达式,它将被求值,否则以 None 替代(类似省略 return 语句结果)。
return 会离开当前函数调用,并以表达式的值 (或 None) 作为返回值。
当 return 将控制流传出一个带有 finally 子句的 try 语句时,该 finally 子句会先被执行然后再真正离开该函数。
def f2():
x =1
print(f2())
None
def f1():
x = 1
return
print(f1())
None
# return 结束函数调用
def f(x):
return x**2
print('end') # retrun 结束函数调用,不会被执行
f(2)
4
# finally 总是被执行再结束函数调用
def f(x):
try:
return 3/x
except ZeroDivisionError as e:
print(e)
finally:
return x, x**2
f(0),f(2)
division by zero
((0, 0), (2, 4))
yield 语句
yield 语句,仅在定义 生成器函数 时使用,并且仅被用于生成器函数的函数体内部。语法如下:
yield from expression
from
和表达式 expression
是可选的,没有表达式默认是 None。
yield 语句整体也是一个可被求值的表达式语句,初始值也是默认 None,可通过 send 方法设置 yield 表达式的值。
在函数定义中使用 yield 使得该定义创建的是生成器函数而非普通函数。当一个生成器函数被调用的时候,它返回一个生成器迭代器。
yield from 相当于将一个可迭代对象 “拆包”,然后逐项被生成器迭代时使用。
# 创建一个简单的生成器函数
def f():
yield
print(f)
# 调用它获得一个生成器
print(f())
# next() 函数迭代生成器获取表达式的值
print(next(f()))
<function f at 0x00000157028A9598>
<generator object f at 0x000001570286CB88>
None
# 获取并设置 yield 语句的值
def f(n):
x = yield n
print(x)
g = f(1)
print(next(g))
# 迭代结束,打印出 yield 语句 x 的初始值为 None
print(next(g,'end'))
1
None
end
# 可通过 send 方法设置当前 yield 表达式的值
# 并返回生成器产生的下一个值
def f(n):
x = yield n
print(f'yield 表达式的值为:{x}')
n += 1
yield n
g = f(0)
next(g), g.send(10)
yield 表达式的值为:10
(0, 1)
def f(*args):
yield from args
g = f(1,2,3)
next(g),next(g),next(g),next(g,'end')
(1, 2, 3, 'end')
def f(arg):
yield from arg
g = f('123')
next(g),next(g),next(g),next(g,'end')
('1', '2', '3', 'end')