Last active
November 7, 2018 15:52
-
-
Save kokumura/080e7154e26ed2e5d8dc767191082519 to your computer and use it in GitHub Desktop.
construct `__all__` automatically in Python
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from typing import Collection, List, Dict | |
class Export: | |
""" | |
construct __all__ using decorator | |
Example: | |
>>> import os, sys | |
>>> from exporter import Export | |
>>> | |
>>> export = Export() | |
>>> __all__ = export.__all__ | |
>>> | |
>>> # all classes or funcions marked with @export are exported. | |
>>> @export | |
>>> def foo_method(): | |
>>> pass | |
>>> | |
>>> class FooClass: | |
>>> pass | |
>>> | |
>>> def bar_method(): | |
>>> pass | |
>>> | |
>>> @export | |
>>> class BarClass: | |
>>> pass | |
>>> | |
>>> # __all__ == ['foo_method', 'BarClass'] | |
""" | |
def __init__(self, all: Collection[str] = None): | |
self._default_all = all or tuple() | |
self._all = list(self._default_all) | |
def export(self, o): | |
if isinstance(o, str): | |
self._all.append(o) | |
elif hasattr(o, '__name__'): | |
self._all.append(o.__name__) | |
return o | |
def __call__(self, *args, **kwargs): | |
return self.export(*args) | |
def build_all(self) -> List[str]: | |
return self._all | |
@property | |
def __all__(self): | |
return self.build_all() | |
class ExportBelow: | |
""" | |
construct __all__ using locals() | |
Example: | |
>>> import os, sys | |
>>> from exporter import ExportBelow | |
>>> | |
>>> def foo_method(): | |
>>> pass | |
>>> | |
>>> class FooClass: | |
>>> pass | |
>>> | |
>>> __all__ = ExportBelow(locals()) | |
>>> # all module level variables below are exported. | |
>>> | |
>>> def bar_method(): | |
>>> pass | |
>>> | |
>>> class BarClass: | |
>>> pass | |
>>> | |
>>> # __all__ == ['bar_method', 'BarClass'] | |
""" | |
def __init__(self, locals_dic: Dict): | |
self._locals_dic = locals_dic | |
self._begin_locals_dic = dict(locals_dic) | |
self._all_list = None | |
self._excludes = ['__all__'] | |
@property | |
def _all(self): | |
if self._all_list is None: | |
self._all_list = list(set(self._locals_dic.keys()) - set(self._begin_locals_dic.keys()) - set(self._excludes)) | |
self._locals_dic = None # release reference to locals | |
self._begin_locals_dic = None | |
return self._all_list | |
def __getitem__(self, item): | |
return self._all.__getitem__(item) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment