库定义中的导入语句似乎未被执行

2 投票
2 回答
12061 浏览
提问于 2025-04-16 12:31

我遇到了一个可能很基础的问题,但作为一个学习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命令行中执行相同的语句(importprint),也会出现同样的问题。

难道在我调用 import project 的时候,datetime 模块不应该自动被导入吗?

非常感谢!

2 个回答

0

可以把 import 语句想象成大概是这样的:

project = __import__('project')

其实,import 语句就是把一个模块的内容赋值给一个变量。虽然在加载模块的时候可能会有一些额外的效果,但在你的代码里,你看到的只是一个简单的名字赋值。

你可以用 from project import * 来引入模块里的所有名字,但不要这样做,因为这样会让你的代码变得很脆弱,维护起来也更困难。更好的做法是只引入整个模块,或者只引入你需要的特定名字。

所以在你的代码中,像这样:

import datetime
from project import Project

就是你应该做的事情。

4

datetime模块只是在project这个命名空间里被引入。所以你可以通过project.datetime.datetime.min来访问它,但其实你应该直接在你的脚本里引入它。

在你的project.py文件中创建的每一个符号(名字),比如你的Project类,都会放在project这个命名空间里,这里面也包括你从其他模块引入的东西。不过,这并没有看起来那么低效——实际上,不管你引入多少次,datetime模块只会被真正引入一次。之后每次引入它时,实际上只是把名字引入到当前的命名空间里,并不会重复进行读取和引入模块的繁重工作。

撰写回答