2017-12-27 2155 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