2010-06-06 25 views
19

我是新來的Python因此如果問題太基本的:)訂單執行和編碼的風格在Python

我已閱讀,Python是從頂部執行請不要火焰我。

如果是這樣的話,爲什麼程序是這樣的:

def func2(): 
    pass 

def func1(): 
    func2() 

def func(): 
    func1() 

if __name__ == '__main__': 
    func() 

所以從我所看到的,主要功能發生在最後的,其他功能都堆積在它的上面。

我說錯了嗎?如果否,爲什麼主函數或函數定義不是從上到下寫的?

編輯:我問,爲什麼我不能做到這一點:

if __name__ == '__main__': 
    func() 

def func1(): 
    func2() 

這不是自然的秩序?你繼續在底部添加東西,因爲它是從上到下執行的。

+0

這與無序執行無關。請參閱http://en.wikipedia.org/wiki/Out-of-order_execution – 2010-06-06 17:42:37

回答

22

def只是創建功能。除了解析語法並將函數與這些名稱綁定之外,不執行任何代碼。

if是實際執行的第一位代碼。如果你先把它放好,並在定義它之前調用一個函數,那麼結果就是一個NameError。因此,您需要在定義函數之後將其放入。

請注意,這不同於PHP或JavaScript,其中函數被'懸掛' - 任何函數定義在處理和解析之前都會被處理。在PHP和JavaScript中,執行你所說的並且在源代碼中定義函數比調用它們的位置是完全合法的。 (JS中的一個細節是定義了像function(){}這樣的函數,而像var func1=function(){};這樣定義的函數不是,我不知道它如何與PHP 5.3中的匿名函數一起工作)。

請參閱此處,cat()將正確打印,並且yip()會給您一個NameError,因爲解析器在您調用它時沒有得到yip()的定義。

def cat(): 
    print 'meowin, yo' 

cat() 

yip() 

def yip(): 
    print 'barkin, yall' 

meowin, yo
Traceback (most recent call last):
File "cat.py", line 5, in
yip()
NameError: name 'yip' is not defined

0

def語句只是定義一個函數 - 它們實際上並沒有運行它,直到函數被調用。因此,爲什麼它們通常在任何代碼使用它們之前都會出現 - 它們將函數設置爲將來使用。

有沒有硬性要求是def聲明任何事情之前到來,這只是相當普遍把__main__代碼在底部(除其他事項外,它明確什麼是在該節的,哪些不是,因爲下面的東西if是該部分的一部分)。它也確保你想從該部分調用的任何東西已經是def'd。

0

的確,約定是將「main」函數放在文件末尾的「if __name__ == '__main__'」語句之上。我認爲這是因爲我們通常希望功能靠近他們的呼叫站點。

至於調用函數上方的被調用函數,我認爲這只是重構的結果。至少在我的情況下,我傾向於編寫一個函數,然後取出一些代碼放入子函數中,這些子函數放在頂部以便我可以看得更清楚。

這只是代碼組織的一種原始形式。如果有更強大的內聚單元,我會試圖將這些功能放到他們自己的模塊中。

1

if __name__ == "__main__"部分在最後,因爲大概無論您的主要功能是否需要腳本中的所有其他定義。如果有其他函數定義低於主要塊,那麼它們將不可能在那裏被使用,因爲在那一點上他們還沒有被解釋者看到。

+2

只要func1已被_defined_ func2調用_called_,您就可以從func2調用func1。 – Weeble 2010-06-06 17:26:10

+0

注意到,刪除。 – detly 2010-06-06 17:35:52

17

Python從上到下執行,但執行「def」塊不會立即執行包含的代碼。相反,它使用當前範圍中的給定名稱創建一個函數對象。考慮Python文件就像你的例子:

def func2(): 
    print "func2" 

def func1(): 
    func2() 

def func(): 
    func1() 

if __name__ == '__main__': 
    func() 

會發生什麼事時,這個腳本執行如下:

首先,在全球範圍內創建函數對象並將其綁定到名爲「FUNC2」 。然後創建一個函數對象並綁定到全局範圍中的名稱「func1」。然後一個叫做「func」。然後執行「if」語句,條件成立並執行「func()」語句。此時「func」是在全局範圍內找到的函數對象,因此它被調用並且其代碼運行。該代碼包含「func1()」語句,該語句已解析爲調用「func1」函數,依此類推。

如果你把「if」語句放在頂部,那麼當它執行的時候,還沒有任何用「func」這個名字定義的東西,所以你會得到一個錯誤。重要的是,「def」語句本身就是一個被執行的語句。它不像其他一些語言中的定義是一種單獨的聲明而沒有執行的順序。

還要注意,只要「if __name__ ...」位在文件的末尾,其他聲明的順序並不重要,因爲當它們中的任何一個被調用時的「def」將會被執行。

+0

這個順序在C語言中很常見,即使在其他函數定義中,函數也必須在使用之前進行聲明。人們使用該命令來避免需要前向聲明。我並不認爲這在Python中是必要的,但我仍然是出於習慣。 – phkahler 2010-06-06 17:43:03

+0

爲什麼**如果__name__ =='__main __':**爲真?請解釋。我投了! – 2017-06-04 19:18:56

+1

@YanKhonski查看https://stackoverflow.com/questions/419163/what-does-if-name-main-do – Weeble 2017-06-06 08:16:30

3

Python通常會自上而下處理命令。但是,函數調用將導致Python執行該函數,並且只有在該調用結束後才繼續向下。

在你的榜樣,Python解釋器將執行以下步驟:

  1. 定義func2
  2. Define func1
  3. 定義func
  4. 過程如果語句if __name__ == '__main__':
  5. 調用func函數(因爲條件爲真)。
  6. 調用func1函數(因爲這就是func所做的)。
  7. 調用func2函數(因爲這就是func1所做的)。
  8. 結束,因爲在完成對func2的呼叫之後,它也完成呼叫func1,因此已完成調用func,這是代碼中的最後一個聲明。
0

對於你的問題(在Python編碼風格)的第二部分,我會看看PEP 8,提供由Guido van Rossum的(在BFDL自己!),並寫了一個風格指南提供了編寫Pythonic代碼的基礎知識。