为什么python允许没有"pass"语句的空函数(带有doc-string)主体?

Day*_*Day 21 python syntax

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
Run Code Online (Sandbox Code Playgroud)

在最近一些类似上述代码的评论中,一位同事问:

为什么method_onepython成功解析和接受?空函数是否需要一个仅包含的体pass?即不应该看起来像这样?

def method_one(self):
    """This is the first method, will do something useful one day"""
    pass
Run Code Online (Sandbox Code Playgroud)

我当时的回答是这样的:

虽然docstring通常不被认为是函数体的一部分,因为它不是"执行"的,所以它被解析为,所以pass可以省略.

本着分享知识问答风格的精神,我想我会在这里发布更严谨的答案.

Day*_*Day 19

根据Python 2.7.5语法规范,它由解析器生成器读取并用于解析Python源文件,函数如下所示:

funcdef: 'def' NAME parameters ':' suite
Run Code Online (Sandbox Code Playgroud)

函数体suite看起来像这样

suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT
Run Code Online (Sandbox Code Playgroud)

在这一直到语法之后,stmt可以是一个expr_stmt,它可以只是一个testlist,它可以只是一个test可以(最终)只是一个atom,它可以只是一个STRING.文档字符串.

以下是语法的适当部分,按正确的顺序进行:

stmt: simple_stmt | compound_stmt
simple_stmt: small_stmt (';' small_stmt)* [';'] NEWLINE
small_stmt: (expr_stmt | print_stmt  | del_stmt | pass_stmt | flow_stmt |
             import_stmt | global_stmt | exec_stmt | assert_stmt)
expr_stmt: testlist (augassign (yield_expr|testlist) |
                     ('=' (yield_expr|testlist))*)
testlist: test (',' test)* [',']
test: or_test ['if' or_test 'else' test] | lambdef
or_test: and_test ('or' and_test)*
and_test: not_test ('and' not_test)*
not_test: 'not' not_test | comparison
comparison: expr (comp_op expr)*
comp_op: '<'|'>'|'=='|'>='|'<='|'<>'|'!='|'in'|'not' 'in'|'is'|'is' 'not'
expr: xor_expr ('|' xor_expr)*
xor_expr: and_expr ('^' and_expr)*
and_expr: shift_expr ('&' shift_expr)*
shift_expr: arith_expr (('<<'|'>>') arith_expr)*
arith_expr: term (('+'|'-') term)*
term: factor (('*'|'/'|'%'|'//') factor)*
factor: ('+'|'-'|'~') factor | power
power: atom trailer* ['**' factor]
atom: ('(' [yield_expr|testlist_comp] ')' |
       '[' [listmaker] ']' |
       '{' [dictorsetmaker] '}' |
       '`' testlist1 '`' |
       NAME | NUMBER | STRING+)
Run Code Online (Sandbox Code Playgroud)

  • 语法规范很难阅读o_O (2认同)
  • @comodoro我迟到了,但它不是严格相同的,如果字符串它成为函数/方法的文档字符串,你可以用`method_one .__ doc__`的`help(method_one)`检索但是其他语句该函数可能没有docstring.我想这并不常见,但存在差异 (2认同)