zoukankan      html  css  js  c++  java
  • 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放置一些公用模块 
    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()

    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("=====未处理完成====")

    commom.py

    RECV_DATA_LIST = list()  # 用来存储数据
    HANDLE_FLAG = False  # 用来标记是否处理完成

    执行结果如下:

    对比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这个值。
  • 相关阅读:
    (Java实现) 洛谷 P1106 删数问题
    (Java实现) 洛谷 P1603 斯诺登的密码
    (Java实现) 洛谷 P1036 选数
    (Java实现) 洛谷 P1012 拼数
    (Java实现) 洛谷 P1028 数的计算
    (Java实现) 洛谷 P1553 数字反转(升级版)
    (Java实现) 洛谷 P1051 谁拿了最多奖学金
    (Java实现) 洛谷 P1051 谁拿了最多奖学金
    (Java实现) 洛谷 P1106 删数问题
    目测ZIP的压缩率
  • 原文地址:https://www.cnblogs.com/testlearn/p/12364724.html
Copyright © 2011-2022 走看看