在 Python 中,允许使用不包含任何语句的空函数体,即使函数具有文档字符串(doc-string)。例如,以下代码定义了一个名为 SomeThing
的类,其中包含两个方法:method_one
和 method_two
。
class SomeThing(object):
"""Represents something"""
def method_one(self):
"""This is the first method, will do something useful one day"""
def method_two(self, a, b):
"""Returns the sum of a and b"""
return a + b
这种写法引发了疑问:为什么 method_one
方法可以通过 Python 解析器而不需要使用 pass
语句来填充函数体?是否应该像下面这样,在函数体中使用 pass
语句?
def method_one(self):
"""This is the first method, will do something useful one day"""
pass
2. 解决方案
Python 的函数语法由 Python 语法规范定义。根据 Python 2.7.5 语法规范,函数的定义如下:
funcdef: 'def' NAME parameters ':' suite
其中,suite
表示函数体,可以是简单的语句块或缩进块。
对于简单的语句块,语法如下:
suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT
其中,simple_stmt
表示简单的语句,可以是表达式语句、打印语句、删除语句、pass
语句、流程控制语句、导入语句、全局语句、执行语句或断言语句。
对于表达式语句,语法如下:
expr_stmt: testlist (augassign (yield_expr|testlist) |
('=' (yield_expr|testlist))*)
其中,testlist
表示测试列表,可以是测试值或测试值的列表。
对于测试值,语法如下:
test: or_test ['if' or_test 'else' test] | lambdef
其中,or_test
表示逻辑或测试,可以是多个逻辑与测试通过逻辑或运算符连接而成。
对于逻辑与测试,语法如下:
and_test: not_test ('and' not_test)*
其中,not_test
表示逻辑非测试,可以是逻辑非运算符与另一个测试值或比较运算连接而成。
对于比较运算,语法如下:
comparison: expr (comp_op expr)*
其中,expr
表示表达式,可以是算术表达式、移位表达式、逻辑与表达式、逻辑异或表达式、逻辑或表达式、比较表达式或测试值。
comp_op
表示比较运算符,可以是小于、大于、等于、大于或等于、小于或等于、不等于、in、not in、is 或 is not。
对于表达式,语法如下:
expr: xor_expr ('|' xor_expr)*
其中,xor_expr
表示逻辑异或表达式,可以是多个逻辑与表达式通过逻辑异或运算符连接而成。
对于逻辑与表达式,语法如下:
and_expr: shift_expr ('&' shift_expr)*
其中,shift_expr
表示移位表达式,可以是多个算术表达式通过移位运算符连接而成。
对于算术表达式,语法如下:
arith_expr: term (('+'|'-') term)*
其中,term
表示项,可以是多个因子通过加法或减法运算符连接而成。
对于因子,语法如下:
factor: ('+'|'-'|'~') factor | power
其中,power
表示幂表达式,可以是原子值或原子值与指数表达式的乘积。
对于原子值,语法如下:
atom: ('(' [yield_expr|testlist_comp] ')' |
'[' [listmaker] ']' |
'{' [dictorsetmaker] '}' |
'`' testlist1 '`' |
NAME | NUMBER | STRING+)
其中,NAME
表示名称,NUMBER
表示数字,STRING
表示字符串。
根据上述语法,一个函数可以具有文档字符串作为其函数体的唯一内容,而无需使用 pass
语句。这是因为文档字符串在语法上被视为函数体的一部分,即使它不会被执行。