为什么在__setattr__中使用__dict__导致__getattr__中的无限循环

时间:2019-01-09 03:40:03

标签: python getattr setattr

我为这个指定的简化Mesh类编写了一个工作程序,但是我无法使其具有数十种方法/属性的实际类工作。 我无法修改真正的Mesh类,也无法使Object类扩展为Mesh。

这很好:


    class Mesh:
        def __init__(self):
            self.hide_render = False


    class Object:
        def __init__(self, mesh_):
            self.mesh = mesh_

        def __getattr__(self, item):
            return self.mesh.__getattribute__(item) # infinite loop in this line

        def __setattr__(self, name, value):
            if name == 'hide_render': # line to replace----------
                self.mesh.__setattr__(name, value)
            else:
                super().__setattr__(name, value)

    ob = Object(Mesh())

    print(ob.hide_render)
    print(ob.mesh.hide_render)
    ob.mesh.hide_render = True
    print(ob.hide_render)
    print(ob.mesh.hide_render)
    ob.hide_render = False
    print(ob.hide_render)
    print(ob.mesh.hide_render)

输出:

    False
    False
    True
    True
    False
    False

但是当我想对真正的Mesh类做同样的事情时,通过将 setattr 方法中的第一行替换为具有“ hide _render”属性以外的内容:     if name not in self.__dict__: 要么     if name in self.mesh.__dict__:

我在 getattr 方法中遇到了无限循环。 为什么?以及如何解决这个问题?

1 个答案:

答案 0 :(得分:2)

self.mesh不存在时,您会遇到问题。如果您尝试将对self.__dict__中尚不存在的对象的所有查找推迟到self.mesh,则在无法查找或分配给self.mesh本身时会遇到问题

有几种方法可以解决此问题。您可以使用self.__dict__['mesh']的{​​{1}}或super().__setattr__调用,而不使用直接分配。或者,您可以在__init__中将名称mesh特殊化:

__setattr__