我正在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()函数已经由文件),在最坏的情况下,它实际上是对无关的实现细节(项目的基础文件结构)的引用,该细节稍后可能会更改,因此我不希望我的用户期望并依赖它未来版本。
python大神给出的解决方案
您尝试做的事情不可能优雅。正如@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']