为什么我不能调用packagename.modulename.foo()?

时间:2009-12-27 19:32:07

标签: python import package

在我工作的python目录中,我创建了:

packagename/__init__.py
packagename/modulename.py
test.py

在modulename.py中我创建了一个空类:

class Someclass(object):
   pass

在test.py中:

import packagename
packagename.modulename.Someclass()

为什么我不能在test.py中调用packagename.modulename.someclass()?

AttributeError: 'module' object has no attribute 'modulename'

我理解正确的方法是:

import packagename.modulename

from packagename import modulename

但是我不明白为什么在我的情况下会出现这个错误。

更新

换句话说,是否有任何方法可以使用distinct命名空间中的所有模块导入包的内容? 我需要正确的pythonic表达式:

from packagename import * as mynamespace

3 个答案:

答案 0 :(得分:2)

Python不会自动递归和导入子包。当你说:

import packagename

这就是它的全部进口。如果你说:

import packagename.modulename

然后它首先导入packagename,然后导入packagename.modulename将对其的引用指定为packagename的属性。因此,当你在代码中说:

packagename.modulename.Someclass()

Python只使用 100%普通属性查找。首先查找当前命名空间中的packagename变量。然后查找modulename对象的packagename属性。然后查找Someclass对象的modulename属性。

如果您忽略了导入packagename.modulename,那么packagename modulename上的AttributeError显然是无属性,此后就是dir()。< / p>

我建议您弹出命令行并导入一些内容,然后使用dir()进行检查。然后导入子包,再次使用from packagename.modulename import SomePackage 。你会很快发现差异。


最后,语法:

import packagename.modulename
SomePackage = packagename.modulename.SomePackage

基本上与此相同:

{{1}}

(当然,它的实现方式不同,但结果大致相同)。

这有帮助吗?

答案 1 :(得分:1)

如果“packagename”包中有100个模块,您是否希望在导入顶级名称时自动导入所有模块?这通常不是一个好主意,因此Python不会这样做。

如果您想自动导入该特定模块,请将其包含在__init__.py中,如下所示:

from packagename import modulename

或者,使用Python 2.5或2.6:

from __future__ import absolute_import
from . import modulename

(在以后的版本中,您可以放弃from __future__部分。)

编辑:没有内置机制要求Python导入包中的所有可能的子模块。这不是一个常见的用例,通过让__init__.py精确导入您想要的内容,可以更好地处理它。可以将一些东西放在一起来完成这项工作(使用__import__()等),但在大多数情况下,最好只是按照描述显式导入所有子模块。

答案 2 :(得分:0)

有些软件包非常大,导入其中的所有内容都需要花费大量时间。最好为导入提供精细的粒度,因此用户只能导入他真正需要的东西。