Как «импортировать *» и вызывать импортированные функции, когда пакет является каталогом, а не файлом - PullRequest
0 голосов
/ 03 декабря 2010

Если я разрабатываю клиент-серверное приложение и у меня есть 3 файла (client.py, server.py и common.py,), а common.py имеет полезную функцию (например, normalize()), это легко сделать из обоихклиент и сервер должны сделать что-то вроде этого:

from common import *

url = normalize(url)

Однако, если по разным странным причинам я предпочел бы иметь отдельные подкаталоги (client, server и common), и каждыйФункция имеет свой собственный файл, похоже, что подобного ярлыка не существует.

Мне нужно возиться с sys.path, затем после импорта мне нужно использовать url=normalize.normalize(url).Я уверен, что мог бы запрограммировать обходной путь, но есть ли уже какой-то Pythonic способ обработки этого, о котором я не знаю?

Обновление: вот как я это сделал после следования совету Игнасиониже:

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

Результат:

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/')

Ответы [ 2 ]

5 голосов
/ 03 декабря 2010

Все, что __init__.py в импорте каталога будет импортировано в import *, если оно не ограничено __all__.

0 голосов
/ 03 декабря 2010

Переместите 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 client, import client.something, from 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

Иногда полезно взглянуть на стандартную библиотеку и посмотреть, как используются такие функции.

...