如何在导入中使用root包?

时间:2016-08-29 22:33:19

标签: python

Ansible项目为例,lib/ansible root directory内有许多其他软件包,比如

ansible/cli
       /errors
       /...many omitted for brevity
       /utils
       /vars
       __init__.py

例如,从ansible/utils/vars.py开始,导入从根ansible / lib目录开始,例如

   from ansible.errors import AnsibleError

from ansible.errors import AnsibleError

而不是

from errors import AnsibleError etc.

我有一个像这样的目录结构的演示项目

beatles/george/harrison.py
       /george/__init__.py
       /john/lennon.py
       /john/__init__.py
       /ringo/starr.py
       /ringo/__init__.py
       /paul/mccartney.py
       /paul/__init__.py
       __init__.py (this __init__.py file is in the beatles dir)
       helpers.py

所以,使用Ansible示例,我尝试(在文件john/lennon.py中)来做

来自beatles.george.harrison导入吉他

但我得到一个错误`没有名为beatles.george.harrison的模块

但是,如果省略beatles包(相当于ansible项目中的ansible),代码可以正常工作

来自george.harrison导入吉他

为什么我的目录结构无法将导入编码为

from beatles.george.harrison import Guitar
来自beatles / john / lennon.py文件的

?如果可能的话,请参考ansible项目进行解释,以便明确为什么它在一种情况下有效但在另一种情况下无效。

>>> from beatles.john.lennon import Guitar Traceback (most recent call last): File "<stdin>", line 1, in <module> ImportError: No module named beatles.john.lennon 
>>> from john.lennon import Guitar >>> Guitar <class 'john.lennon.Guitar'>

2 个答案:

答案 0 :(得分:1)

这里的不同之处在于,当您安装ansible时,它会将文件放入可从sys.path访问的子目录中。例如,它可能会在这里:

/home/leahcim/.local/lib/python2.7/site-packages'

这只是对位置的猜测。 import ansible并在ansible.__file__上查看它最终的实际位置(具体位置取决于几个方面)。

现在,如果你写一个setup.py文件,你也可以在本地看到你的应用:

python setup.py develop

如果您还不想为您的应用编写有效的setup.py,那么您需要找到一些其他方法,以便在sys.path中显示它。

具体来说,你的&#34;披头士乐队的父目录&#34;目录应包含在sys.path中。一种简单的方法是将其导出到环境变量PYTHONPATH中。

答案 1 :(得分:1)

适合我。结构:

.
└── beatles
    ├── george
    │   ├── harrison.py
    │   ├── __init__.py
    ├── __init__.py
    ├── john
    │   ├── __init__.py
    │   ├── lennon.py
    ├── paul
    │   ├── __init__.py
    │   └── mccartney.py
    └── ringo
        ├── __init__.py
        └── starr.py

$ cat beatles/john/lennon.py

from beatles.george.harrison import Guitar

def Guitar(x):
    return "John's guitar"

$ cat beatles/george/harrison.py

def Guitar(x):
    return "George's guitar"

我可以,我的工作目录是beatles文件夹

>>> from beatles.john.lennon import Guitar
>>> Guitar(1)
"John's guitar"

这似乎正是您所描述的设置,但在lennon.pyGuitar导入harrison.py时未提供错误消息。

Python 2.7.6 (default, Jun 22 2015, 17:58:13) 

>>> sys.path
['', '/usr/lib/py...[etc]

这样我的工作目录就是路径中的第一项。你试过安装包吗?或者它在您的工作目录中?