Automatic Attribute Assignment during Class Inheritance

Steven D'Aprano steven at REMOVE.THIS.cybersource.com.au
Thu Sep 10 00:00:21 EDT 2009


On Wed, 09 Sep 2009 20:14:33 -0700, gizli wrote:

> I do not want to force the consumers of this framework to write this
> obscure line of code. I was wondering if it is possible (at class
> definition time) to capture the fact that MyTask extends Task and
> automatically insert the polymorphic_identity key into the
> __mapper_args__ class attribute (with value set to __name__).
> 
> So far, I have not been able to do anything because during class
> definition time, there is no a lot of variables I can access. *self*
> obviously does not work. __name__ and __class__ are also useless.

Class definitions are controlled by the metaclass, which is fairly deep 
magic but not entirely impenetrable. Once you've defined a metaclass to 
use, the consumers will only need to say:

class MyTask(Task):
    __metaclass__ = MyMetaclass

which is less obscure than the alternative. You may even be able to have 
Task use the metaclass, in which case MyTask doesn't need to do anything 
special at all. (I think.)


Another alternative is to use a class decorator:

# You write this and provide it in your API.
def mapper(cls):
    cls.__mapper_args__ = dict(polymorphic_identity=cls.__name__)
    return cls


# The consumer writes this.
@mapper
class MyTask(Task):
    pass


Decorator syntax for classes only works for Python 2.6 or better. In 2.5, 
the consumer would need to write:

class MyTask(Task):
    pass
MyTask = mapper(MyTask)



-- 
Steven



More information about the Python-list mailing list