我见过各种各样的例子和其他类似的问题,但我似乎无法找到正是我的情景相匹配的例子。 我觉得自己像一个总打手问这个,因为有这么多类似的问题,但我似乎无法得到这个工作“正常。” 这里是我的项目:
user_management (package)
|
|------- __init__.py
|
|------- Modules/
| |
| |----- __init__.py
| |----- LDAPManager.py
| |----- PasswordManager.py
|
|------- Scripts/
| |
| |----- __init__.py
| |----- CreateUser.py
| |----- FindUser.py
如果我动“CreateUser.py”到主user_management目录,我可以很容易地使用: "import Modules.LDAPManager"
导入LDAPManager.py ---这个作品。 我不能做什么(这是我想要做的),就是保持CreateUser.py在脚本子文件夹,进口LDAPManager.py。 我希望通过完成这个"import user_management.Modules.LDAPManager.py"
。 这是行不通的。 总之,我可以得到Python文件可以轻松地看在更深的层次,但我不能让一个Python脚本一个目录下,并引用了到另一个。
请注意,我能够解决使用我的问题:
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
import Modules.LDAPManager as LDAPManager
我听说,这是不好的做法和灰心。
在脚本文件的目的是直接执行(在脚本甚至是必要的初始化的.py?)。 我读过,在这种情况下,我应该与-m标志执行CreateUser.py。 我已经试过这方面的一些变化,只是似乎无法得到CreateUser.py识别LDAPManager.py。
如果我移动CreateUser.py
到主user_management目录,我可以很容易地使用: import Modules.LDAPManager
导入LDAPManager.py
---这个作品。
请不要 。 通过这种方式, LDAPManager
通过使用模块CreateUser
不会是一样的一个通过其他进口进口。 当您的模块或酸洗/在unpickle过程中有一定的全局状态这就会产生问题。 避免只是因为模块恰好是在同一个目录中工作的进口。
当你有你要么一个封装结构:
使用相对进口,即如果CreateUser.py
是在Scripts/
:
from ..Modules import LDAPManager
请注意,这是 (注意是过去时态)通过劝阻PEP 8只因为Python的旧版本不支持他们很好,但年前的这个问题得到解决。 PEP 8的最新版本不建议他们以绝对的进口可接受的替代。 其实我喜欢他们里面包。
( 使用全包名称使用绝对导入CreateUser.py
在Scripts/
):
from user_management.Modules import LDAPManager
为了使第二个工作包user_management
应安装在内部PYTHONPATH
。 在开发过程中您可以配置IDE所以,出现这种情况,而无需手动添加呼叫sys.path.append
任何地方。
此外,我觉得很奇怪, Scripts/
是一个子包。 因为在实际安装user_management
模块将下安装site-packages
中发现lib/
目录(取目录用于安装在OS库),而脚本应该一个下安装bin/
目录(取其包含可执行文件您的操作系统)。
事实上,我相信Script/
甚至不应该在user_management
。 它应该是在同一水平user_management
。 这样,您就不必使用-m
,但你只需要确保包可以发现(这又是配置IDE,正确安装包或使用的问题PYTHONPATH=. python Scripts/CreateUser.py
推出使用正确的路径脚本)。
总之, 我会使用层次是:
user_management (package)
|
|------- __init__.py
|
|------- Modules/
| |
| |----- __init__.py
| |----- LDAPManager.py
| |----- PasswordManager.py
|
Scripts/ (*not* a package)
|
|----- CreateUser.py
|----- FindUser.py
随后的代码CreateUser.py
和FindUser.py
应该使用绝对导入来导入模块:
from user_management.Modules import LDAPManager
安装过程中,确保user_management
在什么地方结束PYTHONPATH
,和可执行文件的目录里面的脚本,以便他们能够找到模块。 在开发过程中你要么依靠IDE配置,或在启动CreateUser.py
添加Scripts/
父目录的PYTHONPATH
(我的意思是既包含目录user_management
和Scripts
):
PYTHONPATH=/the/parent/directory python Scripts/CreateUser.py
或者你可以修改PYTHONPATH
全球,这样你就不必指定此各一次。 在UNIX操作系统(在Linux,Mac OS X等),你可以修改shell脚本的一个定义PYTHONPATH
外部变量,在Windows上你必须更改环境变量设置。
增编我相信,如果你正在使用python2,这是更好地确保通过将避免隐相对进口:
from __future__ import absolute_import
在您的模块的顶部。 通过这种方式import X
总是意味着要导入的顶层模块X
,绝不会尝试导入X.py
文件,该文件在同一目录下(如果该目录不在PYTHONPATH
)。 这样做的相对进口的唯一方法是使用显式语法(的from . import X
),这是更好的( 明确优于隐式 )。
这将确保你永远不会发生在使用“假的”隐相对进口,因为这将引发一个ImportError
明确的信号,什么是错。 否则,你可以使用一个模块,这是不是你认为它是。
通过Python 2.5起,您可以使用
from ..Modules import LDAPManager
主导时期带你“上”在你的层次结构的水平。
参见Python文档封装内引用进口。
在“根” __init__.py
你也可以做一个
import sys
sys.path.insert(1, '.')
这将使这两个模块可导入。
文章来源: Python: import module from another directory at the same level in project hierarchy