当包是目录而不是文件时,如何“导入*”并调用导入的函数

时间:2010-12-03 06:34:20

标签: python import client-server packages package

如果我正在开发客户端 - 服务器应用并且有3个文件(client.pyserver.pycommon.py,)并且common.py有一个有用的功能(例如{ {1}}),客户端和服务器很容易做到这样的事情:

normalize()

但是,如果由于各种奇怪的原因,我宁愿拥有单独的子目录(from common import * url = normalize(url) clientserver),并且每个函数都有自己的文件,那么就没有似乎是一个类似的捷径。

我必须摆弄common,然后在导入后我需要使用sys.path。我确信我可以编写一个解决方法,但是有一些Pythonic方法来处理这个我不知道的事情吗?

更新:按照下面的Ignacio建议,我是这样做的:

url=normalize.normalize(url)

结果:

$ 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)

2 个答案:

答案 0 :(得分:5)

目录导入中__init__.py的任何内容都将导入import *,前提是它不受__all__的限制。

答案 1 :(得分:0)

client.py移至client/__init__.py,将server.py移至server/__init__.py,将common移至common/__init__.py,所有内容均与之前一样。

就命名而言,client.py是一个名为client的模块,client/__init__.py是名为client的包的一部分。然后,您可以添加client/something.py并拥有import clientimport client.somethingfrom client import something等类似内容。做事的一般方法也是让client/__init__.py把事情拉到一起:

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

然后可以这样使用:

import client
client.baz()
client.bar.something()
from client import bar
bar is client.bar
from client import foo
foo.baz is client.baz

有时查看标准库并查看如何使用这些功能是有帮助的。