2013-07-18 4 views
18
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 

W niedawnym przeglądzie niektórych kodu podobnego do powyższego, kolega zapytał:Dlaczego python zezwala na pustą funkcję (z ciągiem dokumentów) bez instrukcji "pass"?

Dlaczego method_one pomyślnie analizowany i zaakceptowany przez pytona? Czy pusta funkcja nie potrzebuje ciała składającego się tylko z pass? to znaczy nie powinno tak wyglądać?

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

Moja odpowiedź w tym czasie było coś takiego:

Chociaż docstring zwykle nie jest uważana za część ciała funkcji, ponieważ nie jest „stracony”, jest on analizowany jako taki, więc pass można pominąć.

W duchu sharing knowledge Q&A style, pomyślałem, że zamieszczę tutaj bardziej rygorystyczną odpowiedź.

Odpowiedz

17

Według Python 2.7.5 grammar specification, który jest odczytywany przez generator parsera i służy do analizowania plików źródłowych Python, funkcja wygląda tak:

funcdef: 'def' NAME parameters ':' suite 

Ciało funkcji jest suite który wygląda tak

suite: simple_stmt | NEWLINE INDENT stmt+ DEDENT 

po tym przez całą drogę gramatyki, stmt może być expr_stmt, które mogą być tylko testlist, która może być tylko jeden test, który może (ostatecznie) być po prostu atom, który może być pojedynczym STRING. Docstring.

Oto tylko odpowiednie części gramatyki, w odpowiedniej kolejności do naśladowania przez:

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+) 
+2

że specyfikacja gramatyka jest trudne do odczytania o_O –

Powiązane problemy