To the question:
Why can’t descriptors be instance attributes?
it has been answered that:
descriptor objects needs to live in the class, not in the instance
because that is the way that the __getattribute__ is implemented.
A simple example. Consider a descriptor:
class Prop(object):
def __get__(self, obj, objtype=None):
if obj is None:
return self
return obj._value * obj._multiplier
def __set__(self, obj, value):
if obj is None:
return self
obj._value = value
class Obj(object):
val = Prop()
def __init__(self):
self._value = 1
self._multiplier = 0
Consider the case in which each obj has multiple Prop: I would need to use unique names to identify the values and multipliers (Like here. Having a per instance descriptor object would allow to store the _multiplier (and the _value) in the descriptor itself, simplifying a few things.
To implement per instance descriptor attributes you need to either:
I am aware that similar questions have been raised before, but I have not found a real explanation:
- Why Python is designed this way?
- What is the suggested way to store information that the descriptor needs but is per instance?
Plenty of advanced functionality only works when defined on a class rather than an instance; all of the special methods, for example. As well as making code evaluation more efficient, this makes clear the separation between instances and types which otherwise would tend to collapse (because of course all types are objects).
I’m not sure how recommended this is, but you could in the instance store a mapping from descriptor instance to attribute value:
This has obvious advantages over the other two suggested options:
__getattribute__is inefficient (as all attribute access must go through the overridden special method) and is fragile.As an alternative, you could use a proxy property: