design-patterns/creational/prototype/components.py
Ruidy c8cc1f47b8
Observer (#20)
* doc: create package & update general TOCs

* doc: add documentation

* add code example

* reformat using black
2020-10-06 08:25:18 +02:00

69 lines
2.3 KiB
Python

from __future__ import annotations
import copy
from dataclasses import dataclass
from typing import Any, List
class SelfReferencingEntity:
def __init__(self):
self.parent = None
def set_parent(self, parent):
self.parent = parent
@dataclass
class SomeComponent:
"""
Python provides its own interface of Prototype via `copy.copy` and
`copy.deepcopy` functions. And any class that wants to implement custom
implementations have to override `__copy__` and `__deepcopy__` member
functions.
"""
some_int: int
some_list_of_objects: List
some_circular_ref: Any
def __copy__(self) -> SomeComponent:
"""
Create a shallow copy. This method will be called whenever someone
calls `copy.copy` with this object and the returned value is returned
as the new shallow copy.
"""
# First, let's create copies of the nested objects.
some_list_of_objects = copy.copy(self.some_list_of_objects)
some_circular_ref = copy.copy(self.some_circular_ref)
# Then, let's clone the object itself, using the prepared clones of the
# nested objects.
new = self.__class__(self.some_int, some_list_of_objects, some_circular_ref)
new.__dict__.update(self.__dict__)
return new
def __deepcopy__(self, memo={}) -> SomeComponent:
"""
Create a deep copy. This method will be called whenever someone calls
`copy.deepcopy` with this object and the returned value is returned as
the new deep copy.
What is the use of the argument `memo`? Memo is the dictionary that is
used by the `deepcopy` library to prevent infinite recursive copies in
instances of circular references. Pass it to all the `deepcopy` calls
you make in the `__deepcopy__` implementation to prevent infinite
recursions.
"""
# First, let's create copies of the nested objects.
some_list_of_objects = copy.deepcopy(self.some_list_of_objects, memo)
some_circular_ref = copy.deepcopy(self.some_circular_ref, memo)
# Then, let's clone the object itself, using the prepared clones of the
# nested objects.
new = self.__class__(self.some_int, some_list_of_objects, some_circular_ref)
new.__dict__ = copy.deepcopy(self.__dict__, memo)
return new