定义函数 def,return,yield 语句

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')
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,634评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,951评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,427评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,770评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,835评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,799评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,768评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,544评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,979评论 1 308
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,271评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,427评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,121评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,756评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,375评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,579评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,410评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,315评论 2 352

推荐阅读更多精彩内容