1

I am trying to inject a mixin to a class with a decorator. When the code runs the class no longer has a dict property even though the dir(instance) says it has one. I'm not sure where the property is disappearing. Is there a way that I can get dict or otherwise find the instance's attributes?

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

This code works if the decorator is commented out yet causes an error when the decorator is present. Running on python 3.5.1

1 Answer 1

3

It's not "losing __dict__". What's happening is that your original dummyClass has a __dict__ descriptor intended to retrieve the __dict__ attribute of instances of your original dummyClass, but your decorator puts that descriptor into a new dummyClass that doesn't descend from the original.

It's not safe to use the original __dict__ descriptor with instances of the new class, because there's no inheritance relationship, and instances of the new class could have their dict pointer at a different offset in their memory layout. To fix this, have your decorator create a class that descends from the original instead of copying its dict and bases:

def testDecorator(cls): return type(cls.__name__, (Mixin, cls), {}) 
Sign up to request clarification or add additional context in comments.

2 Comments

Simply excising __dict__ from the mapping passed to type also works (a new __dict__ descriptor is created automatically). Might be a good idea to also remove __weakref__.
Well, Mixin has its own __dict__ descriptor, so it ends up using that one instead of creating a new one, but yeah, removing __dict__ should work.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.