General convention for python libraries that also have an interface module?
Right now I've got a project that has the following layout:
foo/
__init__.py
__main__.py
foo.py
In this case, foo.py
is actually the main api file, so developers are meant t开发者_开发百科o do "from foo import foo", but I also wanted to make it so that end users could just run ~$ foo
and get an interface.
which, when I do a distutils install, creates /usr/bin/__main__.py
because (a) I don't know how to use distutils, [less important] and (b) I am not sure about what is generally considered to be the Right Thing.
As far as I can tell I have three options:
Make distutils smarter, so that
setup.py install
creates the symlink/usr/bin/foo -> $PYTHONLIB/foo/__main__.py
. This is my immediate intuition, and I could probably figure out how to do it, although the things that I'm thinking of doing all feel like hacks and I haven't found anybody talking about this.Rename
__main__.py
to justfoo
before distribution, and modify the call to distutils' setup to besetup(scripts=['foo'], ...)
. This is pretty similar to (1), except for when it happens, I think.Just don't include an interface with a library package. I feel like this depends mostly on the size of the library/interface as to whether it makes sense.
I haven't seen very many packages that include a __main__.py
, if any, so I'm not sure if people just don't use them or I haven't been using the right packages. The fact that I couldn't find any blog posts or articles dealing with __main__.py
and distutils suggests to me that it's not a particularly popular combination, though.
Calling a module __main__.py
is a bad idea, since that name has a special meaning. Instead use a main sentinel in __init__.py
and create a script that does exec python -m foo
.
Combining Ignacio Vazquez-Abrams' answer with some googling that resulted in me finding this article about using _main_.py, I think I'm probably going to go with a layout along the lines of:
foo/
foo/
__main__.py
...
scripts/
foo
where scripts/foo
is just
#!/bin/sh
exec python foo "$@"
This seems like it will install cleanly, and let people use my module without installing, just by doing python path/to/foo
.
精彩评论