python中多模塊導入的注意點


導入模塊常見的方式有  import xxx ,from xxx import yyy  或者 from xxx import yyy as a(為導入包(方法)取別名主要用於防止包名與模塊中的變量重名,從這里也能看出導入的包名(方法)可以看作是一個變量),不同的導入方式最終都能達到使用模塊中某個方法的效果。需要注意的是效果雖然一樣,但是import的指向是不一樣的。舉個實例說明不一樣的地方,以下為代碼:

有四個 py文件 main.py , recv_msg.py , handle_msg.py , commom.py  其中 main主要用來操作其他功能塊 recv_msg,handle_msg分別用於接收和處理數據 common放置一些公用模塊 

commom.py

RECV_DATA_LIST = list()  # 用來存儲數據
HANDLE_FLAG = False  # 用來標記是否處理完成

recv_msg.py

from common import RECV_DATA_LIST
from common import HANDLE_FLAG
# import common


def recv_msg():
    """模擬接收到數據,然后添加到common模塊中的列表中"""
    print("--->recv_msg")
    for i in range(5):
        RECV_DATA_LIST.append(i)


def test_recv_data():
    """測試接收到的數據"""
    print("--->test_recv_data")
    print(RECV_DATA_LIST)


def recv_msg_next():
    """已經處理完成后,再接收另外的其他數據"""
    print("--->recv_msg_next")
    if HANDLE_FLAG:
    # if common.HANDLE_FLAG:
        print("------發現之前的數據已經處理完成,這里進行接收其他的數據(模擬過程...)----")
    else:
        print("------發現之前的數據未處理完,等待中....------")
        

handle_msg.py

from common import RECV_DATA_LIST
from common import HANDLE_FLAG
# import common


def handle_data():
    """模擬處理recv_msg模塊接收的數據"""
    print("--->handle_data")
    for i in RECV_DATA_LIST:
        print(i)

    # 既然處理完成了,那么將變量HANDLE_FLAG設置為True,意味着處理完成
    global HANDLE_FLAG
    HANDLE_FLAG = True
    # common.HANDLE_FLAG = True


def test_handle_data():
    """測試處理是否完成,變量是否設置為True"""
    print("--->test_handle_data")
    if HANDLE_FLAG:
    # if common.HANDLE_FLAG:
        print("=====已經處理完成====")
    else:
        print("=====未處理完成====")
main.py
from recv_msg import *
from handle_msg import *


def main():
    # 1. 接收數據
    recv_msg()
    # 2. 測試是否接收完畢
    test_recv_data()
    # 3. 判斷如果處理完成,則接收其它數據
    recv_msg_next()
    # 4. 處理數據
    handle_data()
    # 5. 測試是否處理完畢
    test_handle_data()
    # 6. 判斷如果處理完成,則接收其它數據
    recv_msg_next()


if __name__ == "__main__":
    main()

執行結果如下:

對比main.py的執行順序其他都好理解,唯獨箭頭處不符合預計,按照代碼邏輯此處預期打印“已處理”,然而結果卻打印“未處理”,通讀代碼推斷原因應該是  HANDLE_FLAG在handle_msg.py的handle_data()方法中沒有被改為Ture。

HANDLE_FLAG為什么沒有被修改為Ture?

在handle_msg.py文件中,HANDLE_FLAG的使用方式為  from common import HANDLE_FLAG  ,該導入方式相當於是在handle_msg.py 生成一個叫做HANDLE_FLAG 的變量,並且這個變量指向的是common.py里面HANDLE_FLAG的值(False),當在執行  HANDLE_FLAG =True 這行代碼時 其實是將變量handle_msg.py中的 HANDLE_FLAG 重新指向了一個新的值為True(這個過程可以理解為賦值的過程,即修改的是變量的指向而不是變量指向的值),此時common里面的HANDLE_FLAG 值依然是False, 所以在recv_msg.py使用 from common import HANDLE_FLAG 導入時,HANDLE_FLAG這個變量仍指向False。

如何解決這個問題?
在handle_msg.py文件中,將HANDLE_FLAG的使用方式改為 import common,再使用common.HANDLE_FLAG 調用即可解決。具體原理可以理解為:在handle_msg.py中生成一個叫做common的變量,這個變量指向的是common文件,而common.HANDLE_FLAG可以理解為指向common文件中的 HANDLE_FLAG 變量名而不是這個變量名的值,所以在handle.py執行 common.HANDLE_FLAG=Ture 讓它的指向從False變成了True后,在recv_msg.py使用 common.HANDLE_FLAG可以獲取到Ture這個值。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM