Automatic Attribute Assignment during Class Inheritance
gizli
mehmetf at gmail.com
Thu Sep 10 02:09:04 EDT 2009
On Sep 9, 9:00 pm, Steven D'Aprano
<ste... at REMOVE.THIS.cybersource.com.au> wrote:
> 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
Steven, thank you. __metaclass__ was exactly what I was looking for.
After a few documents later, I came up with this code:
class PolymorphicSetter(type):
def __new__(cls, name, bases, dictionary):
dictionary['__mapper_args__'] = name
return type.__new__(cls, name, bases, dictionary)
and set this in my Task class:
__metaclass__ = PolymorphicSetter
Also, thank you for the class decorator code. That is what I meant by
class wrapper :) I will keep that as a reference as well.
More information about the Python-list
mailing list