2011-10-26 71 views
3

所有,我在Python今天運行了一個奇怪的驚喜。下面的代碼有效,但似乎違反了python的語法。我不知道爲什麼它沒有通過聲明或一些代碼,但它確實會起作用。Python函數的語法似乎是無效的,但運行

def test(): 
    '''Sample docstring.''' 

for i in range(10): 
    test() 
    print "testing", i 

我想確定它的工作原理,以及它在運行時是否在內存中留下任何令人討厭的位。這可能是我一直試圖追蹤的內存問題的原因。

+3

是不是很簡單的在'測試添加一個'pass'()'的文檔字符串,看看內存泄漏消失? –

回答

11

塊中必須至少有一條語句。獨立的字符串文字被視爲有效的語句,即使它被用作文檔字符串。它不應該導致任何內存泄漏,因爲編譯器會在實際代碼中忽略它。

+0

這是完全正確的。說得好。 –

+0

這是一個簡單的例子。實際的代碼只顯示了「現實世界」中的泄漏,而當我經歷它時,我正在探索可能性。你已經回答了我的問題,謝謝! –

0

docstring也是一個聲明。 (準確的表達語句。)

它從編譯器中得到特殊待遇,但在語法上它是完全有效的語句。

+1

這不是說docstring是一個語句,而是字符串文字是一個語句;可以通過賦給'.__ doc__'在函數之外創建一個docstring,但是如果它沒有語句,那麼它將無法編譯。 –

2

Python的語法在語言參考中進行了解釋。相關配件有:

7.7 Function definitions

... 
funcdef  ::= "def" funcname "(" [parameter_list] ")" ":" suite 
... 

所以,對於一個函數的語法是所有的東西到結腸,隨後suite

7. Compound statements

... 
suite   ::= stmt_list NEWLINE | NEWLINE INDENT statement+ DEDENT 
... 
stmt_list  ::= simple_stmt (";" simple_stmt)* [";"] 
... 

所以一個suite可以是stmt_list或含有至少一個statement ...和一個stmt_list只是一堆由分號在一行連接simple_stmt塊的縮進塊。

最後:

6. Simple statements

simple_stmt ::= expression_stmt 
      | assert_stmt 
      ... 

這表明,simple_statement可以是任意表達式,或者assert或任何其他在名單上。

您可以點擊這些頁面上的鏈接進一步探索。一個expression_stmt只是本身評估的任何表達,如:

dir 
2 
"cat" 
int() 

這是一個完全有效的Python程序,將解析和運行,即使什麼都不做。

函數的文檔字符串也是一個表達式。這只是一個恰好被系統處理的字符串。

不過,特殊處理不是語法的一部分。它發生在另一個階段,在解析器構建其抽象語法樹很久之後。

我會尋求其他的內存問題... :)

+0

+1爲詳細信息,並鏈接到python文件的幾個塵土飛揚的角落。 –