开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜