I'm not convinced this is possible, but I thought I'd ask as I'm new to Python. Given an object with a property which its value is handled by a descriptor; is it possible to know that the given descriptor type was involved?
Example Descriptor:
class Column(object):
def __init__(self, label):
self.label = label
def __get__(self, obj, owner):
return obj.__dict__.get(self.label)
def __set__(self, obj, value):
obj.__dict__[self.label] = value
Test Object:
class Test(object):
name = Column("column_name")
def add(self):
print self.name.__class__
Executing this:
my_test = Test()
my_test.name = "myname"
my_test.add()
This gives: <type 'str'>
which is the data type of the value "myname", is it possible to test for isinstance(self.name, Descriptor) - this returns false, but I want it to return true - or something similar?
Edit - Removed bug of old-style class on Test
Search the object's class and superclasses in method resolution order for the descriptor object:
def find_descriptor(instance, attrname):
'''Find the descriptor handling a given attribute, if any.
If the attribute named attrname of the given instance is handled by a
descriptor, this will return the descriptor object handling the attribute.
Otherwise, it will return None.
'''
def hasspecialmethod(obj, name):
return any(name in klass.__dict__ for klass in type(obj).__mro__)
for klass in type(instance).__mro__:
if attrname in klass.__dict__:
descriptor = klass.__dict__[attrname]
if not (hasspecialmethod(descriptor, '__get__') or
hasspecialmethod(descriptor, '__set__') or
hasspecialmethod(descriptor, '__delete__')):
# Attribute isn't a descriptor
return None
if (attrname in instance.__dict__ and
not hasspecialmethod(descriptor, '__set__') and
not hasspecialmethod(descriptor, '__delete__')):
# Would be handled by the descriptor, but the descriptor isn't
# a data descriptor and the object has a dict entry overriding
# it.
return None
return descriptor
return None