Python: Prototype Pattern

DuPrototype.py

import copy

## 原型模式 Prototype Pattern  DuPrototype。py
class SelfReferencingEntity:
    def __init__(self):
        self.parent = None

    def set_parent(self, parent):
        self.parent = parent


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

    def __init__(self, some_int, some_list_of_objects, some_circular_ref):
        self.some_int = some_int
        self.some_list_of_objects = some_list_of_objects
        self.some_circular_ref = some_circular_ref

    def __copy__(self):
        """
        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=None):
        """
        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.
        """
        if memo is None:
            memo = {}

        # 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

  

main.py

调用:

       ## 原型模式 Prototype Pattern
list_of_objects = [1, {1, 2, 3}, [1, 2, 3]]
circular_ref = DuPrototype.SelfReferencingEntity()
component = DuPrototype.SomeComponent(23, list_of_objects, circular_ref)
circular_ref.set_parent(component)

shallow_copied_component = copy.copy(component)

# Let's change the list in shallow_copied_component and see if it changes in
# component.
shallow_copied_component.some_list_of_objects.append("另一个对象")
if component.some_list_of_objects[-1] == "另一个对象":
     print(
          "向shallow_copied_component添加元素 "
          "some_list_of_objects 添加到组件中"
          "some_list_of_objects."
     )
else:
     print(
          "向shallow_copied_component添加元素 "
          "some_list_of_objects 不会将它添加到组件中"
          "some_list_of_objects."
     )

# Let's change the set in the list of objects.
component.some_list_of_objects[1].add(4)
if 4 in shallow_copied_component.some_list_of_objects[1]:
     print(
          "更改组件的 some_list_of_objects中的对象 "
          "在“shallow_copied_component”中更改该对象 "
          "some_list_of_objects."
     )
else:
     print(
          "更改组件的 some_list_of_objects中的对象 "
          "不会改变“shallow_copied_component”中的对象 "
          "some_list_of_objects."
     )

deep_copied_component = copy.deepcopy(component)

# Let's change the list in deep_copied_component and see if it changes in
# component.
deep_copied_component.some_list_of_objects.append("一个对象")
if component.some_list_of_objects[-1] == "一个对象":
     print(
          "向`deep_copied_component` 中添加元素 "
          "some_list_of_objects将它添加到组件中"
          "some_list_of_objects."
     )
else:
     print(
          "向`deep_copied_component`中添加元素 "
          "some_list_of_objects添加不到组件中"
          "some_list_of_objects."
     )

# Let's change the set in the list of objects.
component.some_list_of_objects[1].add(10)
if 10 in deep_copied_component.some_list_of_objects[1]:
     print(
          "挂起组件的some_list_of_objects中的对象 "
          "在“deep_copied_component”中更改该对象 "
          "some_list_of_objects."
     )
else:
     print(
          "挂起组件的some_list_of_objects中的对象 "
          "在“deep_copied_component”中更改不了该对象"
          "some_list_of_objects."
     )

print(
     f"id(deep_copied_component.some_circular_ref.parent): "
     f"{id(deep_copied_component.some_circular_ref.parent)}"
)
print(
     f"id(deep_copied_component.some_circular_ref.parent.some_circular_ref.parent): "
     f"{id(deep_copied_component.some_circular_ref.parent.some_circular_ref.parent)}"
)
print(
     "^^ 这表明深度复制对象包含相同的引用,它们 "
     "不重复克隆。"
)

  

输出:

 

向shallow_copied_component添加元素 some_list_of_objects 添加到组件中some_list_of_objects.


更改组件的 some_list_of_objects中的对象 在“shallow_copied_component”中更改该对象 some_list_of_objects.


向`deep_copied_component`中添加元素 some_list_of_objects添加不到组件中some_list_of_objects.


挂起组件的some_list_of_objects中的对象 在“deep_copied_component”中更改不了该对象some_list_of_objects.


id(deep_copied_component.some_circular_ref.parent): 2246621676496
id(deep_copied_component.some_circular_ref.parent.some_circular_ref.parent): 2246621676496
^^ 这表明深度复制对象包含相同的引用,它们 不重复克隆。

Process finished with exit code 0

  

posted @ 2022-10-20 21:50  ®Geovin Du Dream Park™  阅读(25)  评论(0编辑  收藏  举报