[Tutor] Metaclass programming
Orest Kozyar
orest.kozyar at gmail.com
Tue Sep 4 15:41:51 CEST 2007
> This could be written
> kwargs.update(zip(argnames, args))
Nice trick! Thanks for the pointer.
> > return type.__call__(cls, kwargs)
>
> You are passing kwargs as a positional argument to __call__(); i.e.
> passing the dict as an ordinary parameter. To use kwargs as
> the keyword dict for the call, use the syntax
> type.__call__(cls, **kwargs)
Great, I did not realize that ** was part of the syntax so couldn't figure
out what the issue was. It works smoothly now.
> I think the problem is elsewhere in your code.
You're right. I just figured out that for some reason, when I use the
SQLAlchemy mapper() function to map my classes to the corresponding table
object, it seems to affect inspect.getargspec().
For example:
from sqlalchemy.orm import mapper
from sqlalchemy import Table, MetaData
import inspect
class Foo:
def __init__(self, x, y):
pass
print inspect.getargspec(Foo.__init__)
>> (['self', 'x', 'y'], None, None, None)
metadata = MetaData()
foo_table = Table('foo', metadata)
mapper(Foo, foo_table)
print inspect.getargspec(Foo.__init__)
>> (['instance'], 'args', 'kwargs', None)
I'm not sure why this would be the case, but is a bit frustrating since I do
need the names of the positional arguments sometimes.
> Why are you doing this?
Partially as an exercise to help me better understand Python inspection as
well as metaclass programming. I also am using it in a EntitySingleton
metaclass that I adapted from the SQLAlchemy wiki
(http://www.sqlalchemy.org/trac/wiki/UsageRecipes/UniqueObject). Some of my
classes have unique constraints, and I want the metaclass to check these
unique constraints and return an object from the database if an object
meeting these constraints already exists.
For example:
class User:
__unique__ = ['firstname', 'lastname']
__metaclass__ = EntitySingleton
def __init__(self, firstname, lastname, password):
pass
The metaclass knows what the "unique" constraints are based on the
__unique__ list, but needs to use inspect.getargspec() to get the variable
names and match them up with the *args list that EntitySingleton.__call__
recieves. At least, that's how I'm trying to do it, but I expect this might
not be the best way to do it? Either case, when the class is mapped to a
database table, I lose all this information, so will need to figure out a
different way of approaching this.
Orest
More information about the Tutor
mailing list