Плагины длы пакета в Python

Содержание
Введение
Пример
Похожие статьи

Введение

PEP 420

Перед изучением этой статьи убедитесь, что вам знакомы темы «sys.path в Python» «Пакеты в Python» «Namespace пакеты в Python»

Пример

Рассмотрим пример подключения плагинов для namespace пакета c помощью pkgutil

plugins ├── bz2-plugin │ └── demo_reader │ └── compressed │ └── bzipped.py ├── core │ └── demo_reader │ ├── compressed │ ├── __main__.py │ ├── multireader.py │ └── util │ ├── __init__.py │ └── writer.py └── gz-plugin └── demo_reader └── compressed └── gzipped.py

# core/demo_reader/multireader.py import importlib import os import pkgutil import demo_reader.compressed def iter_namespaces(ns_pkg): return pkgutil.iter_modules( ns_pkg.__path__, ns_pkg.__name__ + ".") compression_plugins = { importlib.import_module(module_name) for _, module_name, _ in iter_namespaces(demo_reader.compressed) } # This maps file extensions to corresponding open methods. extension_map = { module.extension: module.opener for module in compression_plugins } class MultiReader: def __init__(self, filename): extension = os.path.splitext(filename)[1] opener = extension_map.get(extension, open) self.f = opener(filename, 'rt') def close(self): self.f.close() def read(self): return self.f.read()

# core/demo_reader/util/writer.py import sys def main(opener): f = opener(sys.argv[1], mode='wt') f.write(' '.join(sys.argv[2:])) f.close()

# bz2-plugin/demo-reader/compressed/bzipped.py import bz2 from ..util import writer extension = '.bz2' opener = bz2.open if __name__ == '__main__': writer.main(opener)

# gz-plugin/demo-reader/compressed/bzipped.py import gzip from ..util import writer extension = '.gz' opener = gzip.open if __name__ == '__main__': writer.main(opener)

python -m demo_reader test.gz

data compressed with gz

Похожие статьи
Пакеты в Python
Namespace пакеты в Python
Правильная структура пакета
setuptools
Плагины
Python