Is the name of the second parameter to __deepcopy__ required to be memo?

124 Views Asked by At

Is it required to name the second argument of the __deepcopy__ function memo, in case __deepcopy__ is called with memo as a keyword argument?

If I simply want to exclude instances from deep copies, would:

obj.__deepcopy__ = lambda self, _: self

be fine, or do I need to pay attention to naming the second argument of the lambda function memo in order to not cause any issues?

My initial thoughts are that the parameter's name is part of the function signature, and memo is not documented to be a positional argument, so it should probably be safer to name the second argument memo, and just add a linter exception for marking the argument unused.

1

There are 1 best solutions below

2
gamez_code On

If you want to work within the object, you can do the deep copy as the following code:

class memo:
    def __init__(self, a):
        self.a = a

    def __deepcopy__(self, obj):
        _obj = self.__class__(**self.__dict__) # this line create a copy of the object
        _obj.a = 4 # this line let you modify the object
        return _obj

With this you can create a copy with the custom modification copy.deepcopy(memo_obj).

The deepcopy function simply invokes a method within the class called __deepcopy__, passing one parameter. You are free to choose any name for that parameter that you prefer.

The issue with the lambda is that it is a lambda function and not a method inside the class. Consequently, you cannot pass the self parameter to copy the object.

Using lambda self, memo: self would be incorrect because the deepcopy function is called with the following code:

    151 copier = getattr(x, "__deepcopy__", None)
    152 if copier is not None:
--> 153     y = copier(memo)

In this case, memo takes on the value of self, and the lambda expression has two parameters. This configuration will be outside the scope of the copier function, which expects only one parameter.