Пространство имен и классы - PullRequest
7 голосов
/ 25 февраля 2011

Я пытаюсь написать некоторый (на мой взгляд) читаемый код на Python.Мне нужен модуль, который будет содержать ряд классов.Теоретически я знаю все, что необходимо для этого: я могу просто поместить определения классов в один файл модуля.

В целях удобства чтения я хочу поместить каждое определение класса в отдельный файл (они начинают быть довольно длинными!) и все эти классы в один каталог.Всякий раз, когда я создаю новый файл, хотя его содержимое видно там, где оно мне нужно, определение класса, которое находится внутри, ограничено ненужным модулем.

Как мне это сделать?Как это сделать с помощью Python?

Ответы [ 2 ]

8 голосов
/ 25 февраля 2011

Импортируйте их все в пределах __init__.py, и затем потребитель импортирует пакет.

from .module1 import Class1
from .module2 import Class2
 ...
3 голосов
/ 25 февраля 2011

Если вы хотите избежать жесткого кодирования полных путей, имен файлов, классов и функций во многих местах, вы можете сделать что-то вроде следующего, которое динамически импортирует (почти) все файлы Python, которые он находит в подкаталоге пакета.

Ключ помнит, что файл __init__.py сам по себе является практически неограниченным скриптом Python и поэтому может свободно выполнять довольно сложную обработку для определения того, что находится в пространстве имен пакета.

Файл package\__init__.py:

def _import_package_files():
    """ Dynamically import all the Python modules in this module's sub directory. """
    import os
    import sys
    import traceback

    package_path = os.path.split(__file__)[0]
    package_directory = os.path.split(package_path)[1]

    for fn in os.listdir(package_directory):
        globals_, locals_ = globals(), locals()
        # process all python files in directory that don't start with underscore
        if fn[0] != '_' and fn.split('.')[-1] in ('py', 'pyw'):
            modulename = fn.split('.')[0] # filename without extension
            subpackage = ".".join([package_directory, modulename])
            try:
                module = __import__(subpackage, globals_, locals_, [modulename])
            except:
                traceback.print_exc(file=sys.stdout)
                raise # reraise exception

_import_package_files()

Файл package\Class1.py:

class Class1(object):
    pass

Файл package\Class2.py:

class Class2(object):
    pass

Файл package\Class3.py:

class Class3(object):
    pass

Файл usepackage.py:

import package

print(package.Class1)
print(package.Class2)
print(package.Class3)

Выход из режима работы usepackage.py:

<module 'package.Class1' from 'C:\Files\package\Class1.pyc'>
<module 'package.Class2' from 'C:\Files\package\Class2.pyc'>
<module 'package.Class3' from 'C:\Files\package\Class3.pyc'>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...