Source code for better_dict.io
"""
Module contains classes that allow performing I/O operations on objects.
This module defines classes that serve as mixins for other classes.
These classes extensions inject methods that allow performing I/O
operations on objects.
Classes
-------
This module defines the following classes:
- :class:`.PicklerMixin`: Mixin class that adds methods for pickling objects.
- :class:`.JoblibIOMixin`: Mixin class that adds methods for saving objects as
joblib files.
Examples
--------
The following example shows how to use the :class:`.PicklerMixin` class to
extend other classes, adding methods for pickling objects:
.. code-block:: python
class MyClass(PicklerMixin):pass
my_object = MyClass()
# Save classe instance as pickle file
my_object.to_pickle('my_object.pkl')
# Load class instance from pickle file
MyClass.from_pickle('my_object.pkl')
The same logic applies to the :class:`.JoblibIOMixin` class.
Notes
-----
All I/O classes from this module implement the saving method, using the ``to_``
prefix, and the loading method, using the ``from_`` prefix.
The loading methods are class methods, so they can be called directly from the
class, without the need to instantiate it first.
"""
from __future__ import annotations
import pickle
from pathlib import Path
from typing import Any, Dict
import joblib
[docs]class PicklerMixin:
"""
Mixin class for pickle I/O.
This class allows parent objects to perform I/O operations using pickle.
The methods implemented in this class are:
- :meth:`.PicklerMixin.to_pickle`: Save the object to a pickle file.
- :meth:`.PicklerMixin.from_pickle`: Load the object from a pickle file.
Examples
--------
>>> class MyClass(PicklerMixin):pass
>>> obj = MyClass()
>>> # To save the object to a pickle file:
>>> obj.to_pickle("path/to/file")
>>> # To load the object from a pickle file:
>>> obj.from_pickle("path/to/file")
"""
[docs] def __getstate__(self) -> Dict[str, Any]:
"""Get the state of the object for pickling.
Returns
-------
Dict[str, Any]
State of the object for pickling.
"""
return self.__dict__
[docs] def __setstate__(self, state: Dict[str, Any]):
"""Set the state of the object after unpickling.
Parameters
----------
state : Dict[str, Any]
State of the object after unpickling.
"""
self.__dict__ = state
[docs] def to_pickle(self, path: str):
"""Save the object to a pickle file.
Parameters
----------
path : str
Path to the pickle file.
Raises
------
ValueError
If the path refers to a directory.
"""
_path = Path(path).with_suffix(".pickle")
if _path.is_dir():
raise ValueError(f"{path!r} is a directory.")
with open(_path, "wb") as file:
pickle.dump(self, file)
[docs] @classmethod
def from_pickle(cls, path: str) -> PicklerMixin:
"""Load the object from a pickle file.
Parameters
----------
path : str
Path to the pickle file.
Returns
-------
PicklerMixin
Object loaded from the pickle file.
Raises
------
ValueError
If the path is not a file.
"""
_path = Path(path).with_suffix(".pickle")
if not _path.is_file():
raise ValueError(f"{path!r} is not a file.")
with open(_path, "rb") as file:
# codiga-disable
return cls(pickle.load(file)) # noqa
[docs]class JoblibIOMixin:
"""
Mixin class for joblib I/O.
This class allows parent objects to perform I/O operations using ``joblib``.
The methods implemented in this class are:
- :meth:`.JoblibIOMixin.to_joblib`: Save the object to a joblib file.
- :meth:`.JoblibIOMixin.from_joblib`: Load the object from a joblib file.
Methods
-------
to_joblib(path: str)
Save the object to a joblib file.
from_joblib(path: str)
Load the object from a joblib file.
Examples
--------
Define a class that inherits from :class:`.JoblibIOMixin`:
>>> class MyClass(JoblibIOMixin):pass
>>> obj = MyClass()
Save the object as a ``joblib`` file:
>>> obj.to_joblib("path/to/file")
Load the object from a ``joblib`` file:
>>> obj.from_joblib("path/to/file")
"""
[docs] def to_joblib(self, path: str) -> None:
"""Save the object to a ``joblib`` file.
Parameters
----------
path : str
Path to the ``joblib`` file.
Raises
------
ValueError
If the path refers to a directory.
"""
_path = Path(path).with_suffix(".joblib")
if _path.is_dir():
raise ValueError(f"{path!r} is a directory.")
joblib.dump(self, _path)
[docs] @classmethod
def from_joblib(cls, path: str) -> JoblibIOMixin:
"""Load the object from a ``joblib`` file.
Parameters
----------
path : str
Path to the ``joblib`` file.
Returns
-------
JoblibIOMixin
Object loaded from the ``joblib`` file.
Raises
------
ValueError
If the path is not a file.
"""
_path = Path(path).with_suffix(".joblib")
if not _path.is_file():
raise ValueError(f"{path!r} is not a file.")
return cls(joblib.load(_path)) # noqa