[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