Wrapping#
- class sigmaepsilon.core.wrapping.Wrapper(*args, **kwargs)[source]#
Wrapper base class that makes it easy (and safe) to extend other objects. Based on the provided arguments at initialization, the wrapper either
wraps an existing object at object creation provided as a keyword argument with Wrapper.wrapkey
wraps an existing object at object creation if it is a positional argument and an instance of Wrapper.wraptype
The attributes and methods of the wrapped instance are all accessible through the wrapper.
Using a wrapper is a good idea if you want to easily extend the functionality provided by a class of an external library without having to worry about shadowing an important method and thus risking to break the behaviour of the wrapped object.
Examples
>>> import numpy as np >>> >>> arr = np.eye(3) >>> wrapper = Wrapper(wrap=arr)
Now the wrapped NumPy array is accessible as wrapper.wrapped.
A wrapper class can be used to extend the behaviour:
>>> MyWrapper(Wrapper): >>> wraptype = np.ndarray >>> >>> def invert() -> None: >>> self.wrapped = np.linalg.inv(self.wrapped)
With this solution, you don’t have to worry about shadowing an existing implementation of NumPy arrays. Not that NumPy arrays might not have a method called invert at the time of implementing the class MyWrapper, but it might change in the future. You can even check that internally and get notified:
>>> import warnings >>> >>> MyWrapper(Wrapper): >>> wraptype = np.ndarray >>> >>> def invert() -> None: >>> if hasattr(self.wrapped, "invert"): >>> warnings.warn("'invert' already exists in the object") >>> self.wrapped = np.linalg.inv(self.wrapped)
Then, to wrap a NumPy array, you can do this (since the wraptype attribute is set, the MyWrapper class is going to catch the object to wrap as a positional argument):
>>> wrapper = MyWrapper(arr)
- wrap(obj: Any | None = None) Any [source]#
Wraps the provided object and returns the wrapper instance.
- property wrapped#
Retruns the wrapped object.
- sigmaepsilon.core.wrapping.customwrapper(*, wrapkey: str = 'wrap', wraptype: ~typing.Any = <class 'NoneType'>) Wrapper [source]#
A factory function that returns a class decorator turning a class type into a wrapper type, that either
wraps an existing object at object creation provided as a keyword argument with wrapkey
wraps an existing object at object creation if it is a positional argument and an instance of wraptype
See also
Examples
Take this example from the
Wrapper
class:>>> MyWrapper(Wrapper): >>> wraptype = np.ndarray >>> >>> def invert() -> None: >>> self.wrapped = np.linalg.inv(self.wrapped)
An equivalent implementation of this is the following:
>>> @customwrapper(wraptype=np.ndarray) >>> MyWrapper: >>> def invert() -> None: >>> self.wrapped = np.linalg.inv(self.wrapped)
Notice how the class MyWrapper is not inherited from the Wrapper class.
- sigmaepsilon.core.wrapping.wrap(obj: object) Wrapper [source]#
Wraps an object and returns the wrapper.
See also
Example
>>> import numpy as np >>> wrapper = wrap(np.eye(3))
- sigmaepsilon.core.wrapping.wrapper(BaseType: Any) Wrapper [source]#
Simple class decorator that turns a type into a wrapper with default behaviour.
Notes
This is the same as using the
customwrapper()
with the default values.See also
Example
>>> @wrapper >>> MyWrapper: >>> def invert() -> None: >>> self.wrapped = np.linalg.inv(self.wrapped)