2013-07-30 131 views
1
$ cat declare_funcs.py 
#!/usr/bin/python3 

def declared_after(): 
     print("good declared after") 

declared_after() 

$ python3 declare_funcs.py 
good declared after 

更改呼叫發生之後:聲明函數調用

$ cat declare_funcs.py 
#!/usr/bin/python3 

declared_after() 

def declared_after(): 
     print("good declared after") 

$ python3 declare_funcs.py 
Traceback (most recent call last): 
    File "declare_funcs.py", line 4, in <module> 
    declared_after() 
NameError: name 'declared_after' is not defined 

有沒有辦法申報的功能只有頭就像是在C/C++?

例如:

#!/usr/bin/python3 

def declared_after() # declaration about defined function 

declared_after() 

def declared_after(): 
     print("good declared after") 

我發現這個Declare function at end of file in Python

任何方式似乎有像包裝開始另一個函數,這個包裝必須包裝的函數的聲明之後被調用,這是不是一個出口。是否有更多優雅真python的方式?

+3

您鏈接的解決方案中的答案既是pythonic又是優雅。 –

+0

另一個重複的問題:http://stackoverflow.com/questions/1590608/is-it-possible-to-forward-declare-a-function-in-python – 2rs2ts

回答

4

Python不能這樣工作。 def按照從上到下的順序執行,並與文件的其餘內容一起執行。在將其定義爲可調用對象(例如函數)之前,您無法調用某些對象,即使您有一個可調用的對象,它也不會包含您正在查找的代碼。

這當然不意味着代碼在執行開始之前不會被編譯 - 事實上,它是。但是,當執行def時,declared_after實際上被分配在def塊內的代碼,而不是之前。你拉

任何技巧來排序的達到你想要的效果必須有延遲調用declared_after(),直到它被定義後,例如效果,在另一def塊本身就是後來被稱爲封閉它。

1

一兩件事你可以做的是在主函數封裝的一切:

def main(): 
    declared_after() 

def declared_after(): 
    print("good declared after") 

main() 

然而,問題依然存在,該功能必須在調用定義。這僅適用於因爲main被稱爲AFTER declared_after而被定義。

0

正如zigg寫道的,Python文件是按照從上到下的順序執行的,因此即使您之前可以「聲明」該變量,實際的函數體也只會在函數調用後纔會到達。

通常的辦法來解決,這是隻是有一個main功能,所有的標準執行的事情發生:

def main(): 
    # do stuff 
    declared_after(); 

def declared_after(): 
    pass 

main() 

然後,您可以還與__name__ == '__main__' idiom結合本作的功能只有當你執行直接執行模塊:

def main(): 
    # do stuff 
    declared_after(); 

def declared_after(): 
    pass 

if __name__ == '__main__': 
    main() 
2

您不能在Python中轉發聲明函數。這樣做並沒有什麼意義,因爲Python是動態輸入的。你可以像這樣做一些傻事,並期望它做什麼?

foo = 3 
foo() 
def foo(): 
    print "bar" 

很顯然,你試圖__call__int對象3.這絕對是愚蠢的。

你問你是否可以像在C/C++中那樣轉發聲明。那麼,你通常不會通過解釋器運行C.但是,儘管Python是compiled to bytecode,但python3程序是一個解釋器。

以編譯語言進行前向聲明是有意義的,因爲您只是簡單地建立一個符號及其類型,並且編譯器可以多次運行代碼來理解它。然而,當你使用一個解釋器時,你通常不會有那麼奢侈,因爲你必須通過代碼的其餘部分來找到該前向聲明的含義,並在完成之後再次運行它。

你可以,當然,做這樣的事情:

foo = lambda: None 
foo() 
def foo(): 
    print "bar" 

但你實例化foo不過。一切都必須指向Python中的一個實際的現有對象。

雖然這不適用於defclass陳述。這些會創建一個functionclass對象,但它們不會執行裏面的代碼。因此,在代碼運行之前,您有時間在其中實例化事物。

def foo(): 
    print bar() 
# calling foo() won't work yet because you haven't defined bar() 
def bar(): 
    return "bar" 
# now it will work 

不同的是,你只需創建function對象與變量名foobar分別代表他們。現在可以通過這些變量名稱來引用這些對象。

關於Python通常被解釋的方式(在CPython中),您應該確保在模塊中不執行代碼,除非它們作爲主程序運行,或者除非您希望它們在導入時執行某些操作(一個罕見但有效的案例)。您應該執行以下操作:

  1. 將要執行的代碼放入函數和類定義中。
  2. 除非代碼只在主程序中執行纔有意義,否則將其放入另一個模塊中。
  3. 使用if __name__ == "__main__":創建的代碼塊,如果程序是主程序這將只執行。

事實上,你應該做所有模塊的第三個。你可以簡單地在你不想要運行的主程序的每個文件的底部,這樣寫:

if __name__ = "__main__": 
    pass 

這可以防止任何從模塊是否進口發生。