如何在Python中结束一个函数的def?

2,023 阅读3分钟

问题的提出

给出一个Python中的函数定义,以关键字 def 开始。

def f(x, y):
    p = x * y
    return p

res = f(2, 3)
print(res)
# 6

如何知道一个函数的"def"何时结束?例 如,在Java和C++中,函数是用开括号和闭括号括起来的{...} ,所以函数的结束是不含糊的。

从语法上结束一个函数

在Python中:空白缩进含有意义。内部函数体与它所定义的环境相比是缩进的,默认是四个空位。一旦缩进的程度回到函数定义的程度,函数就在语法上结束了。从形式上看,当函数定义遇到一个与函数定义缩进程度相同的非空行时,函数定义就结束了。这个非空行不是该块的一部分。

请看这个例子,我们在函数定义之外定义了三行--前两行是函数体的一部分,第三行则不是。

def f():
    x = 1 # first line
    x = 2 # second line
x = 3 # third line, not part of f()

所以,如果你运行这个代码片段,只有第三行被执行,因为它不是不执行的函数的一部分。

def f():
    x = 1 # first line
    x = 2 # second line
x = 3 # third line, not part of f()
print(x)
# 3

理论上,你也可以像这样在冒号后面写一个单行的函数体。

def f(): pass

如果你需要在单行函数定义中运行多个表达式,你可以用分号来实现。但是,不建议这样做,因为这样做会损害可读性。

def f(): pass; pass

从语义上结束一个函数

虽然函数定义的语法结束是由缩进程度决定的,但你的程序可能因为多种原因而提前离开函数。

  1. **return** 语句将函数执行的结果反馈给函数的调用者。
  2. **yield**语句用于产生一系列动态生成的值的生成器函数
  3. 在执行完函数定义的最后一行后,Python隐含地添加了一个将被自动执行的return None 语句 (见选项 1)。
  4. Python 可能会引发一个错误,在这种情况下,执行流会离开函数体,错误会传播给调用者并向上传播,直到它被捕获或错误终止程序。

这里有四个函数会因为这四个原因而过早地结束。

def f_1():
    if 2 + 2 == 4:
        return True # Function will end here
    else:
        return False


def f_2():
    yield 2 # Function will end here
    print('hi')


def f_3():
    print('hi')
    print('python') # Function will end here


def f_4():
    x = 3 / 0 # Function will end here (error)
    print(x)

下面是一个执行的例子。

>>> f_1()
True
>>> for i in f_2():
	print(i)

	
2
hi
>>> f_3()
hi
python
>>> f_4()
Traceback (most recent call last):
  File "<pyshell#20>", line 1, in <module>
    f_4()
  File "C:\Users\xcent\Desktop\code.py", line 19, in f_4
    x = 3 / 0 # Function will end here (error)
ZeroDivisionError: division by zero

注意,生成器表达式在检查第二个循环试验中要产生的下一个值时,仍然会执行函数定义中的第二行f_3()