我需要澄清在同一名称空间中共存时如何处理模块和类级别的导入。请参阅以下示例:
使用:
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个例子究竟发生了什么?第二个模块导入是否替换了特定于类的第一个导入?这是否意味着模块和类级别导入不应混合在同一名称空间中?
答案 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()