Reputation: 4593
I am working in Python 3.4.2 on Mac OSX and I have a simple version-controlled Python project whose directory/file structure looks like this:
vcs_projectname/
foo/
__init__.py
simplefunc.py
docs/
other_related_stuff/
The __init__.py
file looks like this:
from .simplefunc import helloworld
__all__ = ['helloworld'] # Not sure whether I really need this line...?
and the simplefunc.py
file looks like this:
def helloworld():
print('Hello world!')
I test my code by changing to a directory outside of the project hierarchy, setting my PYTHONPATH
environment variable (in bash) to point at the vcs_projectname
base directory, and launching ipython:
> cd ~
> export PYTHONPATH=~/vcs_projectname
> ipython
Within ipython, I import the package foo and then view its directory structure, with the following result:
In [1]: import foo
In [2]: dir(foo)
Out[2]:
['__all__',
'__builtins__',
'__cached__',
'__doc__',
'__file__',
'__loader__',
'__name__',
'__package__',
'__path__',
'__spec__',
'helloworld',
'simplefunc']
My question: how do I get rid of the reference to the simplefunc
file module in the package directory structure? This is desirable to do because in the best case it is just useless clutter (we don't need it there since the thing that we actually want, the helloworld()
function, has already been made available at the package level by the __init__.py
file), and in the worst case it's essentially a reference to an irrelevant implementation detail (the underlying file structure of the project) that could change later, and which I therefore don't want my users to come to expect and rely upon in future versions.
Upvotes: 2
Views: 184
Reputation: 4212
What you're trying to do is not possible elegantly. As @Lukas mentioned, there are hacks that can accomplish this.
Instead what I've been following is, create a sub-package named _private
and put all such modules in there. That way when user imports the package, all the exposed APIs are available and private APIs are tucked away inside _private
.
Example:
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"
Importing foo
:
>>> import foo
>>> dir(foo)
['__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__', '_private', 'bar', 'baz']
Upvotes: 3
Reputation: 168626
how do I get rid of the reference to the simplefunc file module in the package directory structure?
You can accomplish your stated goal by adding del simplefunc
to your foo/__init__.py
, like so:
from .simplefunc import helloworld
del simplefunc
__all__ = ['helloworld'] # Not sure whether I really need this line...?
Upvotes: 2