26
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成功解析并接受?空函数不需要由 just 组成的主体pass吗?即不应该是这样的吗?

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

我当时的反应是这样的:

虽然文档字符串通常不被认为是函数体的一部分,因为它不是“执行”的,所以它被解析为这样,所以pass可以省略。

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

4

1 回答 1

21

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

funcdef: 'def' NAME parameters ':' suite

函数体是一个suite看起来像这样

suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT

一直遵循这个语法,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+)
于 2013-07-18T22:36:36.483 回答