如何覆盖 Python 对象的复制/深度复制操作? [英] How to override the copy/deepcopy operations for a Python object?

查看:38
本文介绍了如何覆盖 Python 对象的复制/深度复制操作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我了解复制模块中 copydeepcopy 之间的区别.我之前成功使用过 copy.copycopy.deepcopy,但这是我第一次真正去重载 __copy____deepcopy__ 方法.我已经在 Google 上搜索并查看了内置的 Python 模块,以查找 __copy____deepcopy__ 函数的实例(例如 sets.pydecimal.pyfractions.py),但我仍然不能 100% 确定我做对了.

I understand the difference between copy vs. deepcopy in the copy module. I've used copy.copy and copy.deepcopy before successfully, but this is the first time I've actually gone about overloading the __copy__ and __deepcopy__ methods. I've already Googled around and looked through the built-in Python modules to look for instances of the __copy__ and __deepcopy__ functions (e.g. sets.py, decimal.py, and fractions.py), but I'm still not 100% sure I've got it right.

这是我的场景:

我有一个配置对象.最初,我将使用一组默认值实例化一个配置对象.此配置将移交给多个其他对象(以确保所有对象以相同的配置开始).但是,一旦用户交互开始,每个对象都需要独立调整其配置,而不会影响彼此的配置(这对我来说,我需要制作初始配置的深层副本以进行处理).

I have a configuration object. Initially, I'm going to instantiate one configuration object with a default set of values. This configuration will be handed off to multiple other objects (to ensure all objects start with the same configuration). However, once user interaction starts, each object needs to tweak its configurations independently without affecting each other's configurations (which says to me I'll need to make deepcopys of my initial configuration to hand around).

这是一个示例对象:

class ChartConfig(object):

    def __init__(self):

        #Drawing properties (Booleans/strings)
        self.antialiased = None
        self.plot_style = None
        self.plot_title = None
        self.autoscale = None

        #X axis properties (strings/ints)
        self.xaxis_title = None
        self.xaxis_tick_rotation = None
        self.xaxis_tick_align = None

        #Y axis properties (strings/ints)
        self.yaxis_title = None
        self.yaxis_tick_rotation = None
        self.yaxis_tick_align = None

        #A list of non-primitive objects
        self.trace_configs = []

    def __copy__(self):
        pass

    def __deepcopy__(self, memo):
        pass 

在此对象上实现copydeepcopy 方法以确保copy.copycopy 的正确方法是什么.deepcopy 给我正确的行为?

What is the right way to implement the copy and deepcopy methods on this object to ensure copy.copy and copy.deepcopy give me the proper behavior?

推荐答案

自定义建议位于 文档页面:

类可以使用相同的接口控制他们用来复制的控制酸洗.看说明模块泡菜的信息这些方法.复制模块做不使用 copy_reg 注册模块.

Classes can use the same interfaces to control copying that they use to control pickling. See the description of module pickle for information on these methods. The copy module does not use the copy_reg registration module.

为了让一个类定义自己的复制实现,它可以定义特殊方法 __copy__()__deepcopy__().调用前者来实现浅拷贝手术;没有额外的参数是通过.后者被称为实现深拷贝操作;它传递一个参数,备忘录字典.如果 __deepcopy__()实施需要深入组件的副本,它应该调用deepcopy() 函数与组件作为第一个参数和备忘录字典作为第二个参数.

In order for a class to define its own copy implementation, it can define special methods __copy__() and __deepcopy__(). The former is called to implement the shallow copy operation; no additional arguments are passed. The latter is called to implement the deep copy operation; it is passed one argument, the memo dictionary. If the __deepcopy__() implementation needs to make a deep copy of a component, it should call the deepcopy() function with the component as first argument and the memo dictionary as second argument.

既然您似乎并不关心酸洗定制,那么定义 __copy____deepcopy__ 绝对是适合您的方法.

Since you appear not to care about pickling customization, defining __copy__ and __deepcopy__ definitely seems like the right way to go for you.

具体来说,__copy__(浅拷贝)在你的情况下很容易......:

Specifically, __copy__ (the shallow copy) is pretty easy in your case...:

def __copy__(self):
  newone = type(self)()
  newone.__dict__.update(self.__dict__)
  return newone

__deepcopy__ 会类似(也接受 memo arg),但在返回之前它必须调用 self.foo = deepcopy(self.foo,memo) 用于任何需要深度复制的属性 self.foo(本质上是容器的属性——列表、字典、非原始对象,它们通过它们的 __dict__s).

__deepcopy__ would be similar (accepting a memo arg too) but before the return it would have to call self.foo = deepcopy(self.foo, memo) for any attribute self.foo that needs deep copying (essentially attributes that are containers -- lists, dicts, non-primitive objects which hold other stuff through their __dict__s).

这篇关于如何覆盖 Python 对象的复制/深度复制操作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆