Source code for ClearMap.Utils.Lazy

# -*- coding: utf-8 -*-
"""
Lazy
====

Lazy evaluation attributes.
"""
__author__    = 'Christoph Kirst <christoph.kirst.ck@gmail.com>'
__license__   = 'GPLv3 - GNU General Public License v3 (see LICENSE)'
__copyright__ = 'Copyright © 2020 by Christoph Kirst'
__webpage__   = 'https://idisco.info'
__download__  = 'https://www.github.com/ChristophKirst/ClearMap2'

from importlib import import_module


[docs] def lazy_mixin(class_path): """ Injects mixin methods on first access, then self-destructs. The mixin module (and its deps like matplotlib) is never imported until someone actually calls a mixed-in method. Arguments --------- class_path : str The dotted path to the mixin class, e.g. "ClearMap.Visualization.Plotting.PlottingMixin". """ module_path, mixin_name = class_path.rsplit('.', 1) def decorator(cls): def __getattr__(self, name): mixin = getattr(import_module(module_path), mixin_name) for k, v in vars(mixin).items(): if not k.startswith('_'): setattr(cls, k, v) # patch the class, not the instance del cls.__getattr__ # self-destruct return getattr(self, name) # retry (or AttributeError if truly missing) cls.__getattr__ = __getattr__ return cls return decorator
[docs] class lazyattr: """Attribute whose value is computed on first access.""" __slots__ = ('func',) def __init__(self, func): self.func = func def __get__(self, instance, owner): if instance is None: return self try: value = self.func(instance) except AttributeError as e: raise RuntimeError(e) if value is NotImplemented: return getattr(super(owner, instance), self.func.__name__) setattr(instance, self.func.__name__, value) return value