0

假设我有这样的目录结构:

mydir
    __init__.py
    innerdir
        __init__.py
        mymodule.py

的内容mymodule.py很简单:

def hi():
    print 'hello, welcome'

而两个__init__.pys 都是的。

现在,如果我在mydir目录之外,我打开 Python 提示符并尝试import mydir然后使用mydir.innerdir,我得到一个错误(an NameError: 'innerdir' is not defined)。

如果我进入mydir目录,提示那里并尝试import innerdirinnerdir.mymodule.

我可以成功import mydir.innerdir,但是我只能用它作为mydir.innerdir,而不是作为innerdir

4

2 回答 2

3

你描述的一些东西,我什至不确定你期望它做什么。但是从你的最后一段来看,听起来你已经很接近了,所以让我们从那里开始。

我可以成功导入 mydir.innerdir,但是我只能将其用作 mydir.innerdir,而不能仅用作 innerdir。为什么我必须指定整个路径?

这就是importPython 中的工作原理,即使您忽略包并且只有一堆扁平的东西,甚至只是标准库。例如,如果你import os,你可以做os.listdir('.'),但你不能只做listdir('.')

这里的解决方案与那里的解决方案相同:

from mydir import innerdir

这实际上不是很有用,因为innerdir它是一个没有直接定义的包。您可能真正想做的是from mydir.innerdir import mymodule. 但这就是你问的方法。


如果您想知道为什么import mydir后面跟着mydir.innerdir不起作用,我可以解释一下。

从教程的部分:

…当使用类似的语法时import item.subitem.subsubitem,除了最后一项之外的每一项都必须是一个包;最后一项可以是模块或包,但不能是前一项中定义的类或函数或变量。

所以,你所做的根本不应该做任何有用的事情。但它实际上做了什么?

它像一个模块一样导入包。这意味着你在包本身中定义的任何东西——函数、类,甚至模块——都可以作为mydir. 但这不会自动导入包目录中的任何子包或子模块——请记住,您将其作为模块导入,而不是作为包导入。


如果您询问从内部运行时会发生什么mydir(或将其添加到您的 PYTHONPATH)......好吧,在这种情况下,mydir它根本不是一个包,它只是一个充满模块和包的目录(在这种情况下,只有一个包,innerdir)。这很像做from mydir import innerdir.

于 2013-04-03T23:25:39.727 回答
1

直接导入的包不会自动将子包或子模块放入其命名空间:

>>> import mydir
>>> dir(mydir)
['__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__']

(注意这里没有innerdir。)

但是如果你通过包导入,Python 会将命名空间连接在一起:

>>> import mydir.innerdir
>>> dir(mydir)
['__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__', 'innerdir']
>>> dir(mydir.innerdir)
['__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__']

mymodule(请注意,中没有mydir.innerdir。)

__all__Python 允许您使用 中的魔法变量明确说明要在包中自动包含哪些子模块__init__.py,但默认情况下它只会在代码中运行__init__.py代码而不做任何其他事情。

您可以执行以下任何操作:

import mydir.innerdir.mymodule; mydir.innerdir.mymodule.hi()
from mydir.innerdir import mymodule; mymodule.hi()
from mydir.innerdir.mymodule import hi; hi()

或者,您可以编辑__init__.py文件以包含__all__用于通配符导入的变量。

# file mydir/innerdir/__init__.py
print 'Running mydir/innerdir/__init__.py'
__all__ = ['mymodule']

然后你可以做这样的事情:

from mydir.innerdir import *; mymodule.hi()

更疯狂的是,您可以急切地导入子包和模块(我不推荐这样做!):

# file mydir/__init__.py
print 'Running mydir/__init__.py'
import innerdir

# file mydir/innerdir/__init__.py
print 'Running mydir/innerdir/__init__.py'
import mymodule

现在这些将起作用:

import mydir; mydir.innerdir.mymodule.hi()
from mydir import innerdir; innerdir.mymodule.hi()

您可能想复习一下packages 的文档,它解释了所有这些,并且具有与您在此处显示的完全一样的目录结构。

于 2013-04-03T23:57:56.323 回答