混合注入后Python对象丢失__dict__

Posted

技术标签:

【中文标题】混合注入后Python对象丢失__dict__【英文标题】:Python object losing __dict__ after mixin injection 【发布时间】:2018-06-08 09:57:27 【问题描述】:

我正在尝试将 mixin 注入带有装饰器的类。当代码运行时,该类不再具有 dict 属性,即使 dir(instance) 说它有一个。我不确定财产在哪里消失。有没有办法让我获得 dict 或以其他方式找到实例的属性?

def testDecorator(cls):
    return type(cls.__name__, (Mixin,) + cls.__bases__, dict(cls.__dict__))

class Mixin:         
     pass

@testDecorator
class dummyClass:
    def __init__(self):
        self.testVar1 = 'test'
        self.testVar2 = 3.14

inst = dummyClass()
print(dir(inst))
print(inst.__dict__)

如果装饰器被注释掉但在装饰器存在时会导致错误,则此代码有效。在 python 3.5.1 上运行

【问题讨论】:

【参考方案1】:

这不是“失去__dict__”。发生的事情是您原来的 dummyClass 有一个 __dict__ descriptor 用于检索您原来的 dummyClass 实例的 __dict__ 属性,但是您的装饰器将该描述符放入一个新的 dummyClass 中从原来的下降。

将原始的__dict__ 描述符与新类的实例一起使用是不安全的,因为没有继承关系,并且新类的实例的 dict 指针可能在其内存布局中的不同偏移量处。要解决此问题,请让您的装饰器创建一个继承自原始类的类,而不是复制其字典和基类:

def testDecorator(cls):
    return type(cls.__name__, (Mixin, cls), )

【讨论】:

简单地从传递给type的映射中删除__dict__也可以(自动创建一个新的__dict__描述符)。删除__weakref__ 可能是个好主意。 好吧,Mixin 有自己的 __dict__ 描述符,所以它最终会使用那个描述符而不是创建一个新描述符,但是是的,删除 __dict__ 应该可以。

以上是关于混合注入后Python对象丢失__dict__的主要内容,如果未能解决你的问题,请参考以下文章

python的dir()和__dict__属性的区别

13.py

python遍历并获取对象属性--dir(),__dict__,getattr,setattr

python 面向对象 __dict__

Python __dict__属性详解

为啥从 Python 中的对象继承,在不指定父对象时更改 __dict__ 的类型不会? [复制]