要__deepcopy__的第二个参数的名称是否必须是 memo?

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

提问人:mutableVoid 提问时间:11/16/2023 最后编辑:toyota SupramutableVoid 更新时间:11/17/2023 访问量:105

问:

是否需要命名函数的第二个参数,以防作为关键字参数调用?__deepcopy__memo__deepcopy__memo

如果我只想从深层副本中排除实例,则:

obj.__deepcopy__ = lambda self, _: self

没问题,还是我需要注意命名 lambda 函数的第二个参数以免引起任何问题?memo

我最初的想法是,参数的名称是函数签名的一部分,并且没有被记录为位置参数,因此命名第二个参数可能更安全,只需添加一个 linter 异常来标记未使用的参数。memomemo

Python 深拷贝

评论

0赞 matszwecja 11/16/2023
如果要禁止执行深度复制,请不要实现它或引发异常。
2赞 quamrana 11/16/2023
如果你打算忽略参数,那么除了使用 之外,你可以使用 它可以向其他程序员发出信号,表明你在做什么。另请参阅此对类似问题的回答_*args,**kwargs
1赞 jonrsharpe 11/16/2023
我希望该方法只能由(在 CPython 中至少在位置上传递)调用,而不是直接调用。deepcopymemo

答:

-1赞 gamez_code 11/16/2023 #1

如果要在对象中工作,可以按以下代码执行深层复制:

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

有了这个,您可以创建一个副本 自定义修改 .copy.deepcopy(memo_obj)

该函数只是在类中调用一个方法,称为 ,传递一个参数。您可以自由选择您喜欢的该参数的任何名称。deepcopy__deepcopy__

问题在于它是一个 lambda 函数,而不是类内的方法。因此,您不能传递参数来复制对象。lambdaself

使用将不正确,因为该函数是使用以下代码调用的:lambda self, memo: selfdeepcopy

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

在本例中,memo 的值为 self,lambda 表达式有两个参数。此配置将超出复印机函数的范围,该函数只需要一个参数。

评论

0赞 mutableVoid 11/16/2023
谢谢你的回答!在我的例子中,我想允许对特定的容器进行深度复制,但总是省略特定类型的内容,因此我必须通过返回来实现,并且不能接受您和 matswecja 完全禁止深度复制的建议。我认为在您的实现中,是否应该改为调用的问题可能仍然存在(以防它在某处被称为 kwarg)。重新考虑我的问题,我想我的一些措辞不简洁,我不想禁止深度复制,而是返回 og obj__deepcopy__selfobjmemo
0赞 jonrsharpe 11/16/2023
这似乎没有解决实际问题(除了间接地不命名它)。memo