Импорт классов из разных файлов в подкаталог

Вот структура, с которой я работаю:

directory/ script.py subdir/ __init__.py myclass01.py myclass02.py 

Я хочу импортировать в script.py классы, определенные в myclass01.py и myclass02.py . Если я сделаю:

 from subdir.myclass01 import * 

Он отлично работает для класса, определенного в myclass01.py . Но с этим решением, если в разных subdir есть много классов, определенных в разных файлах, и я хочу импортировать их все, мне пришлось бы набирать одну строку для каждого файла. Для этого должен быть ярлык. Я пытался:

 from subdir.* import * 

Но это не сработало.

EDIT : вот содержимое файлов:

Это __init__.py (используя __all__ как предлагал __all__ ):

 __all__ = ['MyClass01','MyClass02'] 

Это myclass01.py :

 class MyClass01: def printsomething(): print 'hey' 

Это myclass02.py :

 class MyClass02: def printsomething(): print 'sup' 

Это script.py :

 from subdir import * MyClass01().printsomething() MyClass02().printsomething() 

Это трассировка, которую я получаю, когда пытаюсь запустить script.py :

 File "script.py", line 1, in <module> from subdir import * AttributeError: 'module' object has no attribute 'MyClass01' 

  • В Python я могу указать аргумент аргумента функции в терминах других аргументов?
  • Панды долго переходят в широкую форму
  • Как подключить вход к python по строкам из программы linux?
  • Хранение словарей Python
  • Расширенный анализ PDF с использованием Python (извлечение текста без таблиц и т. Д.): Какая лучшая библиотека?
  • Эффективный стандартный базовый вектор с numpy
  • Tweepy twitter oauth аутентификация не возвращает oauth_verifier
  • Получить размер очереди в Pika (AMQP Python)
  • 5 Solutions collect form web for “Импорт классов из разных файлов в подкаталог”

    Хотя имена, используемые там, отличаются от того, что показано в структуре каталогов вашего вопроса, вы можете использовать мой ответ на вопрос под названием Namespacing и classes . Показанный там __init__.py также разрешил бы скрипт usepackage.py который был написан таким образом ( package карт в subdir в вашем вопросе, а Class1myclass01 и т. Д.):

     from package import * print Class1 print Class2 print Class3 

    Редакция (обновлено):

    К сожалению, код в моем другом ответе не совсем делает то, что вы хотите – он только автоматически импортирует имена любых подмодулей пакетов. Чтобы импортировать именованные атрибуты из каждого подмодуля, требуется еще несколько строк кода. Вот модифицированная версия файла __init__.py пакета (который также работает в Python 3.4.1):

     def _import_package_files(): """ Dynamically import all the public attributes of the python modules in this file's directory (the package directory) and return a list of their names. """ import os exports = [] globals_, locals_ = globals(), locals() package_path = os.path.dirname(__file__) package_name = os.path.basename(package_path) for filename in os.listdir(package_path): modulename, ext = os.path.splitext(filename) if modulename[0] != '_' and ext in ('.py', '.pyw'): subpackage = '{}.{}'.format(package_name, modulename) # pkg relative module = __import__(subpackage, globals_, locals_, [modulename]) modict = module.__dict__ names = (modict['__all__'] if '__all__' in modict else [name for name in modict if name[0] != '_']) # all public exports.extend(names) globals_.update((name, modict[name]) for name in names) return exports if __name__ != '__main__': __all__ = ['__all__'] + _import_package_files() # '__all__' in __all__ 

    В качестве альтернативы вы можете поместить вышеуказанное в отдельный собственный файл .py-модуля в каталог пакета и использовать его из __init__.py пакета следующим образом:

     if __name__ != '__main__': from ._import_package_files import * # defines __all__ __all__.remove('__all__') # prevent export (optional) 

    Независимо от того, что вы называете файлом, это должно быть то, что начинается с символа подчеркивания _ поэтому он не пытается import себя рекурсивно.

    Ваш лучший вариант, хотя, вероятно, не самый лучший стиль, заключается в том, чтобы импортировать все в пространство имен пакета:

     # this is subdir/__init__.py from myclass01 import * from myclass02 import * from myclass03 import * 

    Затем в других модулях вы можете импортировать то, что хотите непосредственно из пакета:

     from subdir import Class1 

    Я знаю, что прошло пару месяцев с момента ответа на этот вопрос, но я искал то же самое и перебегал через эту страницу. Я был не очень доволен выбранным ответом, поэтому в итоге я написал свое собственное решение и думал, что поделюсь им. Вот что я придумал:

     # NOTE: The function name starts with an underscore so it doesn't get deleted by iself def _load_modules(attr_filter=None): import os curdir = os.path.dirname(__file__) imports = [os.path.splitext(fname)[0] for fname in os.listdir(curdir) if fname.endswith(".py")] pubattrs = {} for mod_name in imports: mod = __import__(mod_name, globals(), locals(), ['*'], -1) for attr in mod.__dict__: if not attr.startswith('_') and (not attr_filter or attr_filter(mod_name, attr)): pubattrs[attr] = getattr(mod, attr) # Restore the global namespace to it's initial state for var in globals().copy(): if not var.startswith('_'): del globals()[var] # Update the global namespace with the specific items we want globals().update(pubattrs) # EXAMPLE: Only load classes that end with "Resource" _load_modules(attr_filter=lambda mod, attr: True if attr.endswith("Resource") else False) del _load_modules # Keep the namespace clean 

    Это просто импортирует * из всех .py-файлов в каталог пакета, а затем выталкивает публичные только в глобальное пространство имен. Кроме того, он позволяет фильтру, если желательны только определенные публичные атрибуты.

    Я использую этот простой способ:

    1. добавьте каталог в системный путь, затем
    2. import module или from module import function1, class1 в этом каталоге.

    обратите внимание, что module – это не что иное, как имя вашего *.py файла без части расширения.

    Вот общий пример:

     import sys sys.path.append("/path/to/folder/") import module # in that folder 

    В вашем случае это может быть что-то вроде этого:

     import sys sys.path.append("subdir/") import myclass01 # or from myclass01 import func1, class1, class2 # .. etc 
     from subdir.* import * 

    Вы не можете использовать '*' таким образом непосредственно после инструкции from. Вам нужно импортировать импорт. Пожалуйста, ознакомьтесь с документацией Python по импорту и пакетам.

    Python - лучший язык программирования в мире.