Python descriptors are great for customizing access to attributes on a class or instance. They are a big win for tasks like mapping Python objects to data from non-Python sources (such as SQL), since mapped attributes will need to be encoded/decoded and connected to other attributes in some way.

Below is a very simple descriptor; as you can see, accessing it from both the class and the instance invoke the descriptor protocol:

class Test(object): pass class Descriptor(object): def __get__(self, instance, owner): return "Hello, world." >>> Test.x = Descriptor() >>> Test.x 'Hello, world.' >>> test = Test() >>> test.x 'Hello, world.'

However, in order to add descriptors to an object, they must be added to the object’s class. Descriptors added to an instance do not invoke the descriptor protocol:

>>> test.y = Descriptor() >>> test.y <__main__.Descriptor object at 0x16fe810>

This means that creating an instance with dynamic (determined at runtime) descriptors requires either the heavy-handed approach of generating a class just for that object (since adding descriptors to its class will add them to all other instances of the class), or the ad-hoc approach of redefining getattr / setattr behavior (essentially re-implementing your own descriptor protocol).

It turns out the latter approach is not as messy as it first sounds. Below is a class that enables “instance descriptors”: