我在Mac OSX上使用Python 3.4.2,我有一个简单的版本控制的Python项目,其目录/文件结构如下所示:
vcs_projectname/
foo/
__init__.py
simplefunc.py
docs/
other_related_stuff/
__init__.py
文件如下所示:
from .simplefunc import helloworld
__all__ = ['helloworld'] # Not sure whether I really need this line...?
并且simplefunc.py
文件如下所示:
def helloworld():
print('Hello world!')
我通过更改到项目层次结构之外的目录来测试我的代码,将我的PYTHONPATH
环境变量(在bash中)设置为指向vcs_projectname
基本目录,然后启动ipython :
> cd ~
> export PYTHONPATH=~/vcs_projectname
> ipython
在ipython中,我导入包foo,然后查看其目录结构,结果如下:
In [1]: import foo
In [2]: dir(foo)
Out[2]:
['__all__',
'__builtins__',
'__cached__',
'__doc__',
'__file__',
'__loader__',
'__name__',
'__package__',
'__path__',
'__spec__',
'helloworld',
'simplefunc']
我的问题:如何摆脱包目录结构中对simplefunc
文件模块的引用?这是可取的,因为在最好的情况下它只是无用的混乱(我们不需要它,因为我们实际需要的东西,helloworld()
函数,已经在包级别可用通过__init__.py
文件),在最坏的情况下,它本质上是对不相关的实现细节(项目的基础文件结构)的引用,后者可能会在以后更改,因此我不会这样做。希望我的用户在未来的版本中期待和依赖。
答案 0 :(得分:3)
你想要做的事情是不可能优雅的。正如@Lukas所提到的,有些黑客可以做到这一点。
相反,我一直关注的是,创建一个名为_private
的子包,并将所有这些模块放在那里。这样,当用户导入包时,所有公开的API都可用,私有API隐藏在_private
内。
示例:强>
foo/
__init__.py
_private/
__init__.py
test1.py
test2.py
<强> foo/__init__.py
强>
from _private import bar, baz
<强> foo/_private/__init__.py
强>
from test1 import bar
from test2 import baz
<强> foo/_private/test1.py
强>
def bar():
print "bar"
<强> foo/_private/test2.py
强>
def baz():
print "baz"
导入foo
:
>>> import foo
>>> dir(foo)
['__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__', '_private', 'bar', 'baz']
答案 1 :(得分:2)
如何摆脱包目录结构中对simplefunc文件模块的引用?
您可以通过向del simplefunc
添加foo/__init__.py
来实现既定目标,如下所示:
from .simplefunc import helloworld
del simplefunc
__all__ = ['helloworld'] # Not sure whether I really need this line...?