我在项目中使用内部导入时遇到了困难。这是我项目的部分树结构:
app
|- Gui.py
|- Main.py
|- logger.py
|- config.py
|- WebParser (package)
|- __init__.py
|- LinksGrabber.py
|- LyricsGrabber.py
|- ImagesGrabber.py
|- (Many other packages...)
每个软件包的模块都需要logger.py
和config.py
个模块,并且这些模块是独立的(仅使用bulit-in模块)。从内部包中访问这些模块很棘手。
这就是我尝试实现它的方法,用于在WebParser\LinksGrabber.py
中启用配置访问和日志记录功能:
# WebParser\__init__.py:
sys.path.append('..') # for outside-package modules
import config
from logger import log
# WebParser\LinksGrabber.py:
import WebParser
config = WebParser.config
log = WebParser.log
问题:
import WebParser
并使用WebParser.LinksGrabber
和WebParser.LyricsGrabber
,而不会隐式导入它们。这可以通过导入__init__.py
内的模块来完成,但这是不可能的,因为每个包的模块都会导入包本身,并且它会发出递归导入。您能建议更好的实施或不同的代码设计吗?
答案 0 :(得分:1)
您应该通过为app
文件提供__init__.py
。 python相对导入系统仅在包中使用。然后在WebParser模块中,您可以执行from .. import config
,from .. import Gui
等。
至于从其中的软件包导入WebPackage,这有点代码味道。你为什么要那样做?例如,使用相对导入,您可以在ImagesGrabber等中使用from . import LinksGrabber
来访问您需要的内容。如果有许多子模块需要的WebParser包的函数,您应该将它们放到WebParser中的单独模块中。
答案 1 :(得分:1)
我会将整个外部(app)目录变成一个python包(带有__ init __。py)。
app_files
|- ***setup.py***
|- app
|- ***__init__.py***
|- Gui.py
|- Main.py
|- logger.py
|- config.py
|- WebParser (package)
|- __init__.py
|- LinksGrabber.py
|- LyricsGrabber.py
|- ImagesGrabber.py
|- (Many other packages...)
setup.py会像这样简单:
#!/usr/bin/env python
from distutils.core import setup
setup(name='app',
version='1.0',
description='My app',
author='Greg Ward',
packages=['app'],
)
然后你可以运行python setup.py install
,将'app'永久安装到python路径中。
在我看来,这是最好的方法,无需在任何地方使用sys.path hacks。
然后,从python的任何地方,您都可以参考完整虚线路径中的任何文件
即
import app.logger
import app.config
import app.WebParser
只需从导入app.WebParser中获取LinksGrabber和LyricsGrabber的唯一方法就是从app.WebParser .__ init __导入它们。
答案 2 :(得分:0)
您似乎可以在这里使用relative imports:
from .. import config
from ..logger import log