【问题标题】:Understanding Python import priority了解 Python 导入优先级
【发布时间】:2012-12-06 16:40:21
【问题描述】:

我需要澄清一下在同一个命名空间共存时如何处理模块和类级别的导入。请参阅以下示例:

作品:

import datetime
print datetime.datetime.utcnow()

失败:

from datetime import datetime
print datetime.datetime.utcnow()

错误:AttributeError:类型对象'datetime.datetime'没有 属性“日期时间”

作品:

from datetime import datetime # Is this ignored?
import datetime
print datetime.datetime.utcnow()

第三个例子到底发生了什么?第二个模块导入是否替换了特定于类的第一个导入?这是否意味着模块和类级别的导入不应该混合在同一个命名空间中?

【问题讨论】:

    标签: python python-module


    【解决方案1】:

    没有优先级是这样的。结果由import语句的执行顺序决定,如下所示。

    如果您尝试将多个名为 X 的内容导入命名空间,则每次导入都会将 X 重新绑定到它正在导入的任何内容。

    因此,最后一次导入将在相关名称X 内有效。

    这正是您的第三个示例中发生的情况:

    from datetime import datetime # This isn't ignored, but the name is immediately rebound
                                  # by the next line
    import datetime               # Rebinds the name
    

    【讨论】:

      【解决方案2】:

      一些支持 python 的 IDE 会给你解释,但是是的,你正在重新定义(覆盖、替换)第三个示例中的导入。文件中的每个名称都是不同的。如果您需要访问共享名称的模块和类,则需要使用 from datetime import datetime as dt 之类的名称。

      【讨论】:

        【解决方案3】:

        导入实际上只是一个赋值:它在您当前的命名空间中设置一个名称。因此,在第三种情况下,您将名称 datetime 设置为与 datetime 类相同,然后立即将其重新分配给 datetime 模块。

        【讨论】:

          【解决方案4】:

          没有理由这样做:

          from datetime import datetime
          print datetime.datetime.utcnow()
          

          另一方面,这段代码会完全按照你的意愿去做:

          from datetime import datetime
          print datetime.utcnow()
          

          【讨论】:

            【解决方案5】:

            您的第一个示例导入了datetime 模块并在本地命名空间中提供了一个datetime 标签来表示它,然后调用属于datetime 模块的datetime 对象的utcnow() 方法。第二个将datetime.datetime 对象(不是模块)添加到带有标签datetime 的本地命名空间,但是datetime 对象没有datetime 属性,所以你得到了异常。第三个示例将datetime.datetime 对象分配给命名空间中该名称的标签,然后将标签重新分配给datetime 模块。所以忽略与这个问题无关的import 的机制(基本上,如果它们还没有,则将模块添加到sys.modules),你所拥有的相当于:

            datetime = sys.modules['datetime']
            datetime.datetime.utcnow()
            

            然后

            datetime = sys.modules['datetime'].datetime
            datetime.datetime.utcnow()
            

            然后

            datetime = sys.modules['datetime'].datetime
            datetime = sys.modules['datetime']
            datetime.datetime.utcnow()
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2014-09-09
              • 1970-01-01
              • 2022-01-21
              • 2011-05-04
              • 2014-10-23
              • 1970-01-01
              • 1970-01-01
              • 2023-03-12
              相关资源
              最近更新 更多