【问题标题】:Using modules imported from another import使用从另一个导入中导入的模块
【发布时间】:2018-04-06 13:36:20
【问题描述】:

我正在清理一个被重构为更小的 .py 文件的项目。我注意到在各种文件中一次又一次地导入了很多模块。某些语句位于导入另一个文件的文件中,该文件具有与导入文件相同的导入语句。例如:

ma​​in.py

import alt
print (os.getcwd())

alt.py

import os

print(os.getcwd()) 抛出 NameError: name 'os' is not defined。在 alt.py 中执行 import 语句时,os 不应该是 sys.modules 的一部分吗?

是否可以使用由另一个首先导入的模块导入的模块?

【问题讨论】:

  • import os 是否在 python shell 中工作?导入系统是否正常工作?
  • 哪一行报错?
  • @MichaelButscher 查看编辑

标签: python python-3.x import


【解决方案1】:

它们在以下命名空间中可用:

import alt
print (alt.os.getcwd())

【讨论】:

  • @datta “调用范围”是什么意思?
【解决方案2】:

要回答您的直接问题,可以但不推荐。

导入会调整创建它们的命名空间。这意味着alt 有一个属性os 可以在main 中访问为

print(alt.os.getcwd())

但是,这不是推荐的方式,因为它使您不太清楚您正在使用哪个实际的 os 模块。您应该直接在main 中执行import os。这将不会创建一个单独的模块对象,所以不用担心重复模块会弄乱你的内存。

在运行时第一次遇到导入时,会将其添加到字典 sys.modules 中,并以模块的完全限定名称作为关键字。未来的导入语句将在执行任何实际工作之前在 sys.modules 中查找现有参考。

在您的情况下,import alt 将创建一个由sys.modules['alt'] 以及main 中的名称alt 引用的模块。接下来将运行 alt 中的语句 import os。它将创建一个由sys.modules['os']alt.os 引用的模块。如果您在main 中在import alt 之后添加一行import os,它将不会创建和加载另一个模块对象。相反,名称os 将绑定到sys.modules['os'] 指向的同一个对象。

以下三个版本的main都会调用同一个getcwd函数:

  1. 直接导入(推荐):

    import alt
    import os
    print(os.getcwd())
    
  2. 使用alt 中的引用(更难阅读/跟踪):

    import alt
    print(alt.os.getcwd())
    
  3. 使用sys.modules(除非你知道自己在做什么,否则真的不推荐用于生产):

    import alt  # necessary to trigger the actual import
    import sys
    print(sys.modules['os'].getcwd())
    

所有导入都会加载一个完整的模块。这甚至适用于from os import getcwd 形式的导入。模块sys.modules['os'] 仍在创建中。唯一的区别是导入命名空间只能访问名称getcwd,而不是os。在您的情况下,如果 alt 包含 from os import getcwd 而不是 import os,则三种访问方法将更改如下:

  1. 不变。
  2. print(alt.getcwd()) 因为 alt.os 不再存在。
  3. 不变。

【讨论】:

    【解决方案3】:

    您仅在alt 的子模块级别中导入osos 就是说只能通过alt.os 访问。解决这个问题的方法是将所有从 alt 导入为from alt import *,但这不是你应该做的......

    作为一般经验法则,您应该在当前处理的模块的顶层重新导入直接调用的模块。 因此在 main.py:

     import os
    

    一切都很好

    【讨论】:

    • AFAIK 你不能使用 'alt.py' 导入,而是使用 'alt'。
    【解决方案4】:

    你这样写

    __author__ = 'kerberos'
    __date__ = '2017/10/25 20:48 '
    import alt
    print(alt.os.getcwd())
    

    这是结果:

    C:\Users\Administrator\Desktop\11

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-04-23
      • 1970-01-01
      • 2020-05-18
      • 1970-01-01
      • 2021-01-15
      • 1970-01-01
      • 1970-01-01
      • 2014-04-30
      相关资源
      最近更新 更多