Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
带有自定义_getattr和_setattr的Python深度复制___Python_Python 2.7_Copy_Getattr - Fatal编程技术网

带有自定义_getattr和_setattr的Python深度复制__

带有自定义_getattr和_setattr的Python深度复制__,python,python-2.7,copy,getattr,Python,Python 2.7,Copy,Getattr,我实现了一个类,它可以区分一组固定的实例属性(我们称之为元属性)和一组任意的其他实例属性 它有自定义的\uuuuu getattr\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu class MyClass(object): def __init__(self, meta1, meta2, **other_attr): super(MyClass, self).__

我实现了一个类,它可以区分一组固定的实例属性(我们称之为元属性)和一组任意的其他实例属性

它有自定义的
\uuuuu getattr\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

class MyClass(object):

    def __init__(self, meta1, meta2, **other_attr):
        super(MyClass, self).__setattr__('meta1', meta1)
        super(MyClass, self).__setattr__('meta2', meta2)
        super(MyClass, self).__setattr__('params', {})

        self.params = {key: other_attr[key] for key in other_attr}


    # this is called when default lookup finds nothing
    def __getattr__(self, key):
        print('__getattr__({})'.format(key))
        try:
            return self.params[key]
        except KeyError:
            raise AttributeError(key)


    # this is called always
    def __setattr__(self, key, value):
        print('__setattr__({}, {})'.format(key, value))
        if key in self.__dict__:
            super(MyClass, self).__setattr__(key, value)
        else:
            self.params[key] = value
这很好,所有元属性直接进入实例的
\uu dict\uu
,而所有其他属性进入
参数
字典:

obj1 = MyClass(meta1 = 'foo', meta2 = 'bar', x=1, y=2, z=3)
obj1.w = 4
print(obj1.__dict__)
输出:

除非我尝试
deepcopy
我的对象时,它会做一些奇怪的事情:

import copy
obj1 = MyClass(meta1='foo', meta2='bar', x=1, y=2, z=3)
obj2 = copy.deepcopy(obj1)
输出:


最后,它确实创建了一个副本,但为什么它要调用这么多的
\uuuuuGetAttr\uuuuuuuuuuuuuuuuuuuuu

你应该这样做

return super().__getattribute__('params')[key]

这会导致递归查找(请记住,
obj2
不是通过
初始化的

你应该这样做

return super().__getattribute__('params')[key]

谢谢,成功了。但为什么它不会导致无限递归,而是在某个点停止?@spiderface,我得到
RuntimeError:调用Python对象时超过了最大递归深度。也许您尝试了一个版本,但异常句柄略有不同,这很奇怪。我还发现,我不必从
\uuu getattribute\uuu
返回值,只需调用它,然后返回
return self.params[key]
就足够了。对我来说,从python 2.7切换到python 3.7是个问题。getattribute解决了这个问题。谢谢,成功了。但为什么它不会导致无限递归,而是在某个点停止?@spiderface,我得到
RuntimeError:调用Python对象时超过了最大递归深度。也许您尝试了一个版本,但异常句柄略有不同,这很奇怪。我还发现,我不必从
\uuu getattribute\uuu
返回值,只需调用它,然后返回
return self.params[key]
就足够了。对我来说,从python 2.7切换到python 3.7是个问题。getattribute解决了这个问题。
return self.params[key]
return super().__getattribute__('params')[key]