Pyhton - if __name__ == "__main__":

工欲善其事,必先利其器

# 環境:Python3.6 + win10
# 目錄結構:
D:\test\        # 目錄
    ├─ t1.py    # 文件
    └─ t2.py    # 文件

讓模塊如腳本同樣運行

在Python中,能夠說,每個py文件均可以說是一個模塊,那麼每個模塊不單單能被調用,也要負責自己的邏輯,如咱們在模塊t1中定義了一個登陸函數並實現登陸邏輯:python

# t1.py
def login(user, pwd):
    if user == '張開' and pwd == '666':
        return 'login successful'
    return 'login error'


user, pwd = input('user: ').strip(), input('pwd: ').strip()
print(login(user, pwd))
t1.py

那麼,這個模塊在本身使用的時候,確定沒有問題。可是有一天,這個牛逼的模塊被別人使用了,在t2中調用了t1的註冊功能:ide

# t1.py
def register():
    user, pwd = input('user: ').strip(), input('pwd: ').strip()
    if user == '張開' and pwd == '666':
        return 1
    return 0


def login(user, pwd):
    if user == '張開' and pwd == '666':
        return 'login successful'
    return 'login error'


user, pwd = input('user: ').strip(), input('pwd: ').strip()
print(login(user, pwd))
被t2.py 調用了的t1.py
# t2.py
import t1
def register():
    if t1.register():
        return 'register successful'
    return 'register error'
print(register())

'''
user: a
pwd: a
login error
user: a
pwd: a
register error
'''
t2.py

那麼,在t2模塊內部要實現註冊的時候,想到t1不是實現了一個註冊的功能了嗎?咱們就要避免重複造輪子,就直接調過來用了,可是問題來了,當咱們在調用一個模塊的時候,該模塊內的代碼會先執行一遍,也就是t2模塊示例代碼最後展現的交互結果。當t2模塊內的代碼執行到import t1的時候,觸發了本來t1模塊的執行,t1模塊內部代碼從上往下執行,就執行到了登陸邏輯。等登陸邏輯執行完畢,程序回到t2模塊繼續往下執行。也就執行到了t2內部的註冊函數的執行。而t2的註冊函數此時又調用了t1模塊的註冊的函數的執行,等註冊邏輯執行完畢,程序往下繼續執行——沒有代碼,程序結束。函數

由上述示例能夠見到,咱們在t2模塊調用t1模塊的時候,只想調用註冊函數,並不想觸發t1登陸邏輯的執行,那麼,該怎麼辦呢?ui

if __name__ == "__main__":

咱們首先看一下模塊內自帶都有哪些屬性:spa

# t1.py
print(dir())
'''
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__']
'''

在上述的打印列表內,此時,__name__屬性在這裏對咱們有幫助,那麼咱們來研究一個__name__屬性是什麼鬼?code

咱們先在各自模塊內部打印一下__name__屬性。blog

# t1.py
print('module t1.__name__:', __name__, type(__name__))
'''
module t1.__name__: __main__ <class 'str'>
'''
# t2.py
# import t1
print('module t2.__name__: ', __name__, type(__name__))
'''
module t2.__name__:  __main__ <class 'str'>
'''

經過上例能夠看到,各模塊各自運行的結果一致,__name__屬性都返回了一個str類型的__main__結果,你可能說,這沒啥啊,扯半天淡就這看這個了?別急,咱們放開t2模塊的import t1註釋再看:ip

# t1.py
print('module t1.__name__:', __name__, type(__name__))
'''
module t1.__name__: __main__ <class 'str'>
'''
# t2.py
import t1
print('module t2.__name__: ', __name__, type(__name__))
'''
module t1.__name__: t1 <class 'str'>
module t2.__name__:  __main__ <class 'str'>
'''

經過執行t2模塊,發現一個有趣的現象,在導入t1的時候,觸發了t1模塊的執行,可是,看看此時t1的打印是什麼,沒錯,是t1的模塊名!而單獨運行t1的時候,結果仍不變,仍是__main__。字符串

那麼,由此能夠作些手腳了,咱們經過__name__返回不一樣的字符串(本身調用返回__main__,被調用時返回本身的模塊名),來解決上面那個登陸邏輯被執行的問題。那麼,咱們就在t1中加上一句話:input

# t1.py
def register():
    user, pwd = input('user: ').strip(), input('pwd: ').strip()
    if user == '張開' and pwd == '666':
        return 1
    return 0


def login(user, pwd):
    if user == '張開' and pwd == '666':
        return 'login successful'
    return 'login error'


if __name__ == '__main__':
    user, pwd = input('user: ').strip(), input('pwd: ').strip()
    print(login(user, pwd))
t1.py
# t2.py
import t1
def register():
    if t1.register():
        return 'register successful'
    return 'register error'
print(register())
'''
user: 張開
pwd: 666
register successful
'''
t2.py

在t1模塊中,當__name__屬性返回是字符串__main__的時候,這說明是這次執行是t1模塊本身被本身調用,那麼咱們就把想要實現的邏輯放到該if語句內,代表本身調用時執行。

而當別的模塊如t2調用t1的時候,__name__屬性返回了t1的模塊名,那麼t1不等於__main__,t1模塊內部的if語句也就不會執行。這樣就解決了上例中登陸的問題。 


that's all

相關文章
相關標籤/搜索