混合注入后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__的主要内容,如果未能解决你的问题,请参考以下文章