Welcome, guest | Sign In | My Account | Store | Cart
class NamedDescriptor(object):
    def __init__(self):
        # Name of the attribute, will be set by the classes with
        # the meta class DescriptorNameGetterMetaClass
        self.name = None

    def __get__(self, obj, type=None):
        if obj:
            # at the moment, we return the name of the descriptor, 
            # you can change this line to adapt to your needs
            return self.name
        else:
            return self

    def __set__(self, adaptor, value):
        if adaptor:
            # change the name, you can change this line to adapt to your needs
            self.name = value
        else:
            raise AttributeError('Cannot set this value')


class NamedDescriptorResolverMetaClass(type):
    '''
    This is where the magic happens.
    '''
    def __new__(cls, classname, bases, classDict):
        # Iterate through the new class' __dict__ and update all recognised NamedDescriptor member names
        for name, attr in classDict.iteritems():
            if isinstance(attr, NamedDescriptor):
                attr.name = name
        return type.__new__(cls, classname, bases, classDict)

    
class DescriptorHost(object):
    '''
    The Descriptor gets its name automatically even before any instance of the class is created,
    thanks MetaClass!
    >>> DescriptorHost.myFunDescriptor.name
    'myFunDescriptor'

    In our case, the NamedDescriptor returns it's name when being looked for from the host instance:
    >>> dh = DescriptorHost()
    >>> dh.myFunDescriptor
    'myFunDescriptor'
    '''
    __metaclass__ = NamedDescriptorResolverMetaClass

    myFunDescriptor = NamedDescriptor()


if __name__ == "__main__":
    import doctest
    doctest.testmod()

Diff to Previous Revision

--- revision 2 2010-10-19 22:25:50
+++ revision 3 2010-10-19 22:55:16
@@ -21,7 +21,11 @@
 
 
 class NamedDescriptorResolverMetaClass(type):
+    '''
+    This is where the magic happens.
+    '''
     def __new__(cls, classname, bases, classDict):
+        # Iterate through the new class' __dict__ and update all recognised NamedDescriptor member names
         for name, attr in classDict.iteritems():
             if isinstance(attr, NamedDescriptor):
                 attr.name = name

History