了解Python导入优先级

时间:2012-12-06 16:40:21

标签: python python-module

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

使用:

import datetime
print datetime.datetime.utcnow()

失败:

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

错误:AttributeError:类型对象'datetime.datetime'没有   属性'datetime'

使用:

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

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

5 个答案:

答案 0 :(得分:5)

没有优先权。结果由执行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

答案 1 :(得分:2)

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

答案 2 :(得分:1)

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

答案 3 :(得分:0)

您的第一个示例导入datetime模块并在表示它的本地命名空间中提供datetime标签,然后调用属于该utcnow()对象的datetime方法。 datetime模块。第二个将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()

答案 4 :(得分:0)

没有理由这样做:

from datetime import datetime
print datetime.datetime.utcnow()
另一方面,这段代码完全符合您的要求:

from datetime import datetime
print datetime.utcnow()