from 和 import 导入的区别

本文探讨了Python中from和import导入的不同之处,详细解释了变量在不同情况下的共享机制,并通过实例演示了两种导入方式的实际应用及其对内存和命名空间的影响。
部署运行你感兴趣的模型镜像

from 和 import 导入的区别

  • import 导入一定能实现变量的全局共享
  • from 导入不一定能实现变量的全局共享,只有定义的是可变类型才能全局共享,不变类型无法全局共享,类似于全局变量和局部变量
  • 在实际开发中,应该选择使用 from xx import yy 这种精准的导入方式
  • 不推荐使用 from xx import * 这种导入方式
    • 缺点一 :如果导入的模块变量太多则会占用大量内存,程序运行性能会降低
    • 缺点二 :变量太多容易导致自己定义的变量和导入的变量重名,会出现bug。
  • import导入的使用场景 :导入系统模块,或者导入需要进行全局共享的模块

通过自定义模块来验证两者的区别

from 导入

  • 定义公共模块 common
RECV_DATA_LIST = list()
HANDLE_FLAG = False

- 定义接收数据和处理数据模块 recv_msg, handle_msg

from common import RECV_DATA_LIST
from common import HANDLE_FLAG


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:
        print("------发现之前的数据已经处理完成,这里进行接收其他的数据(模拟过程...)----")
    else:
        print("------发现之前的数据未处理完,等待中....------")
from common import RECV_DATA_LIST  
from common import HANDLE_FLAG 


def handle_data():
    """模拟处理recv_msg模块接收的数据"""
    print("--->handle_data")
    for i in RECV_DATA_LIST:
        print(i)
    global HANDLE_FLAG
    HANDLE_FLAG = True


def test_handle_data():
    """测试处理是否完成,变量是否设置为True"""
    print("--->test_handle_data")
    if HANDLE_FLAG:  # False
    # if common.HANDLE_FLAG:  # True
        print("=====已经处理完成====")
    else:
        print("=====未处理完成====")
  • 定义 main 模块
from recv_msg import *
from handle_msg import *


def main():
    """测试 from 导入模块"""
    recv_msg()
    test_recv_data()
    recv_msg_next()
    handle_data()
    test_handle_data()
    recv_msg_next()


if __name__ == "__main__":
    main()

- 打印结果

--->recv_msg
--->test_recv_data
[0, 1, 2, 3, 4]
--->recv_msg_next
------发现之前的数据未处理完,等待中....------
--->handle_data
0
1
2
3
4
--->test_handle_data
=====已经处理完成====
--->recv_msg_next
------发现之前的数据未处理完,等待中....------

此时 common 模块里的 RECV_DATA_LIST,HANDLE_FLAG 导入到模块 recv_msg 和 handle_msg 中会有差别
RECV_DATA_LIST为列表是可变类型,故会全局共享,所以打印结果为 [0, 1, 2, 3, 4]
HANDLE_FLAG 为 bool 类型是不可变类型,故不会全局共享,可通过 关键字 global 实现全局共享

import 导入

导入的变量全部是全局共享

您可能感兴趣的与本文相关的镜像

Python3.10

Python3.10

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

### Python中 `from module import *` `import module` 的区别Python中,`from module import *` `import module` 是两种不同的模块导入方式,它们在作用域、性能推荐用法上存在显著差异。 #### 1. **作用域** - 使用 `import module` 导入模块时,模块中的所有内容都被封装在一个独立的命名空间中。这意味着要访问模块中的属性或函数时,必须通过模块名作为前缀来调用[^1]。 ```python import math result = math.sqrt(16) ``` - 使用 `from module import *` 导入模块时,模块中的所有公共名称(即不在模块的 `__all__` 列表中被限制的内容)都会直接导入到当前命名空间中[^3]。这使得可以直接使用这些名称,而无需模块名前缀。 ```python from math import * result = sqrt(16) ``` #### 2. **性能** - 在性能方面,`import module` `from module import *` 的实际运行时性能差异通常可以忽略不计,因为两者最终都加载了整个模块[^4]。然而,`from module import *` 可能会导致代码执行速度略微减慢,尤其是在模块包含大量符号时,因为它需要将所有符号复制到当前命名空间中。 - 此外,如果多次使用 `from module import *`,可能会导致命名冲突,从而影响代码的可读性维护性。 #### 3. **推荐用法** - 推荐优先使用 `import module`,因为它明确地定义了模块的作用域,并避免了潜在的命名冲突问题。 - 只有在特定场景下,例如交互式解释器中快速测试某些功能时,才建议使用 `from module import *`。即使在这种情况下,也应确保了解模块的内部结构以避免意外覆盖现有变量。 - 对于标准库中的某些模块(如 `math`),由于其设计初衷就是方便直接使用,因此可以适当放宽对 `from math import *` 的限制[^2]。 ```python # 推荐用法 import math result = math.sqrt(16) # 不推荐用法(除非明确知道风险) from math import * result = sqrt(16) ``` #### 示例代码对比 ```python # 使用 import module import os print(os.getcwd()) # 使用 from module import * from os import * print(getcwd()) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值