Deepcopy不尊重元类 [英] deepcopy does not respect metaclass

查看:81
本文介绍了Deepcopy不尊重元类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类,根据设计,该类必须遵循 singleton 模式.因此,我继续使用 metaclass 实现了它.一切工作都很好,直到报告了一个错误为止,该错误总结说我的 singleton 类的deepcopy -ied实例不是同一实例.

I have a class which, by design, must follow the singleton pattern. So I went ahead and implemented it using a metaclass. Everything worked nicely until a bug was reported which, in summary, said that deepcopy-ied instances of my singleton class were not the same instances.

我可以通过从基类 singleton 继承来解决此错误,但是我宁愿不这样做,原因是

I can get around this bug by inheriting from a base singleton-type class, but I'd rather not, for reasons pointed out in this question.

此问题的工作示例如下:

A working example of this issue is presented below:

class SingletonMeta(type):
    def __init__(cls, name, bases, dict):
        super(SingletonMeta, cls).__init__(name, bases, dict)
        cls.instance = None 
    def __call__(cls,*args,**kw):
        print "SingletonMeta __call__ was called"
        if cls.instance is None:
            cls.instance = super(SingletonMeta, cls).__call__(*args, **kw)
        return cls.instance

class MyClass1(object):
    __metaclass__ = SingletonMeta

class SingletonBase(object):
    _instance = None
    def __new__(class_, *args, **kwargs):
        print "SingletonBase __new__ was called"
        if not isinstance(class_._instance, class_):
            class_._instance = object.__new__(class_, *args, **kwargs)
        return class_._instance

class MyClass2(SingletonBase):
  pass

from copy import deepcopy as dcp

mm1 = MyClass1()
mm2 = dcp(mm1)
print "mm1 is mm2:", mm1 is mm2

mb1 = MyClass2()
mb2 = dcp(mb1)
print "mb1 is mb2:", mb1 is mb2

输出:

SingletonMeta __call__ was called
mm1 is mm2: False
SingletonBase __new__ was called
SingletonBase __new__ was called
mb1 is mb2: True

您能给我一些有关如何解决此问题的指示吗?我正在运行Python 2.7.X

Can you give me any pointers as to how should one resolve this issue? I'm running Python 2.7.X

推荐答案

copy模块上的文档说:

为了让一个类定义其自己的副本实现,它可以定义特殊的方法__copy__()__deepcopy__(). [...] 后者被称为实现深度复制操作.它传递了一个参数,即备忘字典. [...]

In order for a class to define its own copy implementation, it can define special methods __copy__() and __deepcopy__(). [...] The latter is called to implement the deep copy operation; it is passed one argument, the memo dictionary. [...]

因此,如果您声明它们返回self,则应该可以解决问题.

So if you declare these to return self, that ought to do the trick.

这篇关于Deepcopy不尊重元类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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