2017-12-27 898 views
1

我试图注入一个mixin与一装饰类后失去__dict__。当代码运行该类已不再具有即使目录(实例)说,它有一个字典财产。我不确定房屋在哪里消失。有没有一种方法,我可以得到字典或以其他方式找到实例的属性?Python对象混入注射

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__) 

如果装饰被注释掉但此代码导致错误时,装饰是存在的。运行在蟒蛇3.5.1

回答

3

这不是“失去__dict__”。发生了什么事是你的原始dummyClass有一个__dict__descriptor旨在检索原始dummyClass实例的__dict__属性,但是您的装饰器将该描述符放入不会从原始下降的新dummyClass

将原始__dict__描述符与新类的实例一起使用是不安全的,因为不存在继承关系,并且新类的实例的内存布局中的dict指针可能位于不同的偏移处。为了解决这个问题,有你的装饰打造,从原来的下降,而不是复制它的字典和基础类:

def testDecorator(cls): 
    return type(cls.__name__, (Mixin, cls), {}) 
+1

只需切除'从传递给'type'映射__dict__'也可以(一个新的'__dict__'描述符是自动创建的)。也许删除'__weakref__'也是一个好主意。 – BrenBarn

+0

好了,'Mixin'都有自己的'__dict__'描述符,所以它使用一个,而不是创建一个新的,但是,是消除结束了'__dict__'应该工作。 – user2357112