| 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 |