How to 'import *' and call imported functions when package is directory not file
If I'm developing a client-server app and have 3 files (client.py
, server.py
, and common.py,
) and common.py
has a useful function (e.g. normalize()
), it's easy from both client and server to do something like this:
from common import *
url = normalize(url)
However if, for various strange reasons, I'd rather have separate subdirectories (client
, server
, and common
), and each function had its own file, there doesn't seem to be a similar shortcut.
I have to fiddle with sys.path
, then after the import I need to use url=normalize.normalize(url)
. I'm sure I could program a workaround, but is there already some Pythonic way of handling this that I'm unaware of?
Update: here's how I did it after following Ignacio's advice below:
$ cat common/__init__.py; client/login.py jcomeauictx.myopenid.com
import os, sys
for module in os.listdir(os.path.dirname(__file__)):
print >>sys.stderr, 'module: %s' % module
name, extension = os.path.splitext(module)
if extension == '.py' and not name.startswith('_'):
importer = 'from %s import %s' % (name, name)
print >>sys.stderr, 'import 开发者_高级运维statement: %s' % importer
exec(importer)
Result:
module: __init__.py
module: normalize.py
import statement: from normalize import normalize
module: __init__.pyc
module: normalize.pyc
('http://www.myopenid.com/server', 'http://jcomeauictx.myopenid.com/')
Anything the __init__.py
within the directory imports will be imported on import *
provided it's not restricted by __all__
.
Move client.py
to client/__init__.py
, server.py
to server/__init__.py
and common
to common/__init__.py
and all will work as before.
As far as naming is concerned, client.py
is a module called client
, client/__init__.py
is part of a package called client
. You could then add client/something.py
and have import client
, import client.something
, from client import something
and things like that. The general way of doing things is also to have client/__init__.py
just pulling things together:
client/__init__.py
:
from client.foo import *
from client import bar
client/foo.py
:
__all__ = ('baz',)
def baz(): pass
client/bar.py
:
def something(): pass
This can then be used like this:
import client
client.baz()
client.bar.something()
from client import bar
bar is client.bar
from client import foo
foo.baz is client.baz
It's helpful at times to look at the standard library and see how such features are used.
精彩评论