簡體   English   中英

在python中,為什么只有在調用另一個模塊的方法時才會執行類體中的代碼?

[英]In python,why does the code in class body gets executed only when a method of another module is called?

與Java不同,在python中將模塊導入另一個模塊並調用模塊的方法時,為什么主體中的代碼會被執行而不是只執行方法中的代碼?

示例(取自另一個SO問題):

提交one.py

def func():
    print("func() in one.py")

print("top-level in one.py")

if __name__ == "__main__":
    print("one.py is being run directly")
else:
    print("one.py is being imported into another module")

文件two.py

import one

print("top-level in two.py")
one.func()

if __name__ == "__main__":
    print("two.py is being run directly")
else:
    print("two.py is being imported into another module")

當我運行這個:

python two.py

我明白了:

top-level in one.py
one.py is being imported into another module
top-level in two.py
func() in one.py
two.py is being run directly

如果我只想執行one.pyfunc()方法,那就是我選擇導入然后調用它的原因,我應該怎么做? 為什么它首先被執行? 我知道它導入時會因為語句import one而被調用。 尋找促使python設計師以這種方式做到的事情!

編程語言可以有幾種不同的語法元素。 例如,大多數語言都有不同的語句和表達式。 有些語言,比如Java,在頂層有其他語法元素。 例如,您不能在頂級或類中編寫一些語句,但如果您想將類定義放在頂級或類中的方法中,那就沒問題了。

或許,您可以將Java視為在頂層具有聲明性部分,一旦您進入更深層,就會切換到命令式(語句),然后可能會更進一步表達。 但Python並沒有真正起作用。 Python確實區分了表達式和語句,但它並沒有真正具有頂級聲明性語法元素。 也許你在想這個:

def greet(name):
    print("Hello, {}!".format(name))

...就像在Java中一樣,因為它只能出現在某個特定的上下文中。 但是沒有:在Python中,函數定義是一個語句,就像一個類定義一樣,也是一個賦值。

由於這種設計,“只導入定義”是不可行的:為了創建定義,必須運行創建定義的代碼。

我懇請你想一想以下案例。 在Python中,如果你想創建一個枚舉(沒有花哨的新enum模塊),你可能會這樣做:

FOO, BAR, BAZ = range(3)

對於人眼來說,這可能是我們在導入模塊時想要存在的定義。 但是,這與__main__可能存在的類似的東西有什么根本的不同?

name = input("What's your name? ")

確實沒有什么區別,因此Python不會嘗試區分它們; 導入模塊時,代碼將被執行。


額外獎勵:Java中的類似行為

想一想:

public class Test {
    static {
        System.out.println("Wait, what? Code is running without being called?");
    }

    public static void main(String[] args) {
        System.out.println("Nothing to see here, move along now...");
    }
}

Java和Python之間的關鍵區別(在本例中)是Java有一個單獨的編譯步驟 - 使用javac創建類文件。 然而,使用Python,這個編譯是在運行時完成的。 因此,當您導入模塊時,Python必須將整個模塊源代碼編譯為字節代碼。 這包括所有這些打印語句以及創建函數和類。 你問的問題就是要求javac只編譯.java文件的一部分。

它被執行,因為在第一次導入時,模塊中的所有代碼都會被執行, 包括函數定義 如果您不希望執行代碼,請將其放在主節中。

在Python中導入模塊時,將執行整個文件。 這將創建作為模塊一部分的所有函數和變量。 它不區分僅執行函數或類語句。

我相信在庫中擁有可執行代碼的一般模式是:

# one.py
def func():
    print "In file!"

def main():
    # do stuff here
    pass

if __name__=="__main__":
    main()

然后你可以直接執行python one.py文件,也可以import one並使用one.func()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM