James Tauber

journeyman of some

blog > 2006 > 05 > 14 >

Class Definitions Inside Functions

For a while, I've been defining functions in Python that define other functions and return them, taking advantage of lexical scoping and the first-class status of functions:

def foo(x): def bar(y): return x + y return bar

(yes, I realise you can also do this with a lambda expression)

But it all of a sudden occurred to me that you can probably define parameterised classes within functions and return them. Sure, enough, you can:

def foo(x): class bar: def __init__(self, y): self.z = x + y return bar

So foo isn't a factory producing objects, it's a factory producing classes.

This probably isn't news to most of you, but I think it's pretty cool that this works! Looking back, I can think of heaps of times I've wanted to parameterise classes and this would have been perfect.

Comments (4)

AdSR on May 15, 2006:

Still, it's a nice pattern. I suppose it could do a lot of what metaclasses can, in some cases more readably.

Jayson Vantuyl on May 19, 2006:

I actually like this too, although I find that anything too clever with metaclasses, dynamically generated functions/classes, or iterators breaks when you try to serialize (via pickle or whatever).

I really wish we could tackle THAT problem, but I fear we'd end up reinventing LISP again.

fwiffo on May 24, 2006:

You can do some pretty fancy stuff if you then inherit from your factory generated class. For example, let's say you made a factory that automatically created a form validator class based on a SQLObject class (forgive my formatting):

=======================================

class Foobar(SQLObject):
----created = DateCol(default=DateTime.now)
----title = StringCol(length=255)
----dueDate = DateTime()
----comments = StringCol()

function Validator(soSchema):
----# Generate a form validator class for SQLobject schema and return it
----...
----...

class FoobarValidator(Validator(Foobar)):
----dueDate = SpecialDateValidator()

=======================================

SpecialDateValidator might be some sort of variant of a normal date validator that has some special behavior that is more restrictive than normal, like making sure the date is in the future or a certain time zone or something.

[crossing fingers that formatting comes out OK]

James Tauber on May 25, 2006:

Very cool fwiffo!

Add a Comment

Created: May 14, 2006
Last Modified: May 14, 2006
Author: James Tauber