库定义中的导入语句似乎未被执行
我遇到了一个可能很基础的问题,但作为一个学习Python的新手,我为此困扰了好几个小时。文档到现在为止也没有给我答案。
问题是,当我从一个Python脚本中导入一个模块时,这个模块里的导入语句似乎没有被执行。我的情况如下:
我有一个文件叫做 project.py(也就是一个Python库),内容是这样的:
import datetime
class Project:
""" This class is a container for project data """
title = ""
manager = ""
date = datetime.datetime.min
def __init__( self, title="", manager="", date=datetime.datetime.min ):
""" Init function with some defaults """
self.title = title
self.manager = manager
self.date = date
这个库后来在一个脚本(file.py
)中被使用,脚本开头是这样的:
import project
print datetime.datetime.min
然后问题就出现在我尝试用Python执行这个脚本 file.py
时。Python会报出一个NameError错误,内容如下:
Traceback (most recent call last):
File "file.py", line 3, in <module>
print datetime.datetime.min
NameError: name 'datetime' is not defined
其实如果我直接在Python命令行中执行相同的语句(import
和 print
),也会出现同样的问题。
难道在我调用 import project
的时候,datetime
模块不应该自动被导入吗?
非常感谢!
2 个回答
可以把 import
语句想象成大概是这样的:
project = __import__('project')
其实,import
语句就是把一个模块的内容赋值给一个变量。虽然在加载模块的时候可能会有一些额外的效果,但在你的代码里,你看到的只是一个简单的名字赋值。
你可以用 from project import *
来引入模块里的所有名字,但不要这样做,因为这样会让你的代码变得很脆弱,维护起来也更困难。更好的做法是只引入整个模块,或者只引入你需要的特定名字。
所以在你的代码中,像这样:
import datetime
from project import Project
就是你应该做的事情。
datetime
模块只是在project
这个命名空间里被引入。所以你可以通过project.datetime.datetime.min
来访问它,但其实你应该直接在你的脚本里引入它。
在你的project.py
文件中创建的每一个符号(名字),比如你的Project
类,都会放在project
这个命名空间里,这里面也包括你从其他模块引入的东西。不过,这并没有看起来那么低效——实际上,不管你引入多少次,datetime
模块只会被真正引入一次。之后每次引入它时,实际上只是把名字引入到当前的命名空间里,并不会重复进行读取和引入模块的繁重工作。