| Conditions | 6 |
| Total Lines | 87 |
| Code Lines | 21 |
| Lines | 0 |
| Ratio | 0 % |
| Changes | 0 | ||
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
| 1 | """This module is responsible to provide a formal way of registering phi functions |
||
| 75 | @classmethod |
||
| 76 | def register(cls, phi_name=''): |
||
| 77 | """Add a new phi function to phi function registry and notify listeners/observers. |
||
| 78 | |||
| 79 | Use this decorator around either a callable function (defined with the 'def' python special word) or a class |
||
| 80 | with a takes-no-arguments (or all-optional-arguments) constructor and a __call__ magic method. |
||
| 81 | |||
| 82 | All phi functions are expected to be registered with a __name__ and a __doc__ attribute. |
||
| 83 | |||
| 84 | You can select your custom phi_name under which to register the phi function or default to an automatic |
||
| 85 | determination of the phi_name to use. |
||
| 86 | |||
| 87 | Automatic determination of phi_name is done by examining either the __name__ attribute of the function or the |
||
| 88 | class name of the class. |
||
| 89 | |||
| 90 | Example: |
||
| 91 | |||
| 92 | >>> from so_magic.data.features.phi import PhiFunctionRegistry, PhiFunctionRegistrator |
||
| 93 | |||
| 94 | >>> registered_phis = PhiFunctionRegistry() |
||
| 95 | |||
| 96 | >>> @PhiFunctionRegistrator.register() |
||
| 97 | ... def f1(x): |
||
| 98 | ... return x * 2 |
||
| 99 | Registering input function f1 as phi function, at key f1. |
||
| 100 | |||
| 101 | >>> input_value = 5 |
||
| 102 | >>> print(f"{input_value} * 2 = {registered_phis.get('f1')(input_value)}") |
||
| 103 | 5 * 2 = 10 |
||
| 104 | |||
| 105 | >>> @PhiFunctionRegistrator.register() |
||
| 106 | ... class f2: |
||
| 107 | ... def __call__(self, data, **kwargs): |
||
| 108 | ... return data + 5 |
||
| 109 | Registering input class f2 instance as phi function, at key f2. |
||
| 110 | |||
| 111 | >>> input_value = 1 |
||
| 112 | >>> print(f"{input_value} + 5 = {registered_phis.get('f2')(input_value)}") |
||
| 113 | 1 + 5 = 6 |
||
| 114 | |||
| 115 | >>> @PhiFunctionRegistrator.register('f3') |
||
| 116 | ... class MyCustomClass: |
||
| 117 | ... def __call__(self, data, **kwargs): |
||
| 118 | ... return data + 1 |
||
| 119 | Registering input class MyCustomClass instance as phi function, at key f3. |
||
| 120 | |||
| 121 | >>> input_value = 3 |
||
| 122 | >>> print(f"{input_value} + 1 = {registered_phis.get('f3')(input_value)}") |
||
| 123 | 3 + 1 = 4 |
||
| 124 | |||
| 125 | Args: |
||
| 126 | phi_name (str, optional): custom name to register the phi function. Defaults to automatic computation. |
||
| 127 | """ |
||
| 128 | def wrapper(a_callable): |
||
| 129 | """Add a callable object to the phi function registry and preserve info for __name__ and __doc__ attributes. |
||
| 130 | |||
| 131 | The callable object should either be function (defined with def) or a class (defined with class). In case of |
||
| 132 | a class the class must have a constructor that takes no arguments (or all arguments are optional) and a |
||
| 133 | __call__ magic method. |
||
| 134 | |||
| 135 | Registers the callable as a phi function under the given or automatically computed name, makes sure the |
||
| 136 | __name__ and __doc__ attributes preserve information and notifies potential listeners/observers. |
||
| 137 | |||
| 138 | Args: |
||
| 139 | a_callable (Callable): the object (function or class) to register as phi function |
||
| 140 | """ |
||
| 141 | if hasattr(a_callable, '__code__'): # it is a function (def func_name ..) |
||
| 142 | logging.info("Registering input function %s as phi function.", a_callable.__code__.co_name) |
||
| 143 | key = phi_name if phi_name else cls.get_name(a_callable) |
||
| 144 | print(f"Registering input function {a_callable.__code__.co_name} as phi function, at key {key}.") |
||
| 145 | cls._register(a_callable, key) |
||
| 146 | else: |
||
| 147 | if not hasattr(a_callable, '__call__'): |
||
| 148 | raise RuntimeError("Expected an class definition with a '__call__' instance method defined 1." |
||
| 149 | f" Got {type(a_callable)}") |
||
| 150 | members = inspect.getmembers(a_callable) |
||
| 151 | if ('__call__', a_callable.__call__) not in members: |
||
| 152 | raise RuntimeError("Expected an class definition with a '__call__' instance method defined 2." |
||
| 153 | f" Got {type(a_callable)}") |
||
| 154 | instance = a_callable() |
||
| 155 | instance.__name__ = a_callable.__name__ |
||
| 156 | instance.__doc__ = a_callable.__call__.__doc__ |
||
| 157 | key = phi_name if phi_name else cls.get_name(instance) |
||
| 158 | print(f"Registering input class {a_callable.__name__} instance as phi function, at key {key}.") |
||
| 159 | cls._register(instance, key) |
||
| 160 | return a_callable |
||
| 161 | return wrapper |
||
| 162 | |||
| 221 |