Concrete classes -- stylistic question

Ian Bicking ianb at colorstudy.com
Fri Oct 11 09:06:28 CEST 2002


On Fri, 2002-10-11 at 01:31, Alex Martelli wrote:
> Pretty good!  A metaclass that only defines __new__, as metaMetaBunch
> does, is roughly equivalent to a factory function, such as yours.  Even 
> then, of course, using a metaclass lets you use normal class syntax rather
> than function-call syntax  --  class XX(blah): etc  rather than
> XX = blah(etc)  --  but metaclasses do offer more.
> 
> Say that you have metaMetaBunch in some library, and a new
> requirement comes up -- in some cases you want repr(X), where
> X is a class with that meta, to follow the usual convention, so that
> eval(repr(X)) == X.  If type(X) is forced upon you, i.e. if you do NOT
> use a custom meta, you just can't -- you don't have any control on
> the results of repr(X) nor on the comparison of two such classes.

Yes, I hadn't realized it exactly, but I have run up against this
problem with a relational-object mapper that I wrote.  In it, you
created a class, and in particular the class would have an instance
variable _columns.  Then you'd run a function against it, and it would
create methods to fetch and set columns, with caching and all that.  The
other mapper I'd looked at (MiddleKit) accomplished similar things, but
with code generation, which I didn't like.

But the code lacked a certain flexibility.  In particular, I'd want to
have certain things triggered when some columns were set, or any number
of little hooks and the sort.  Of course, using a more conventional
inheritance structure, you'd do something like:

class MyTable(AutoGeneratedTable):

    def setName(self, value):
        # some action that you want triggered when the name is changed...
        AutoGeneratedTable.setName(self, value)

But I couldn't do that, since there was no parent class.  Instead I had
to create two methods for every setter or getter, and if I wanted to
customize I'd use "self.reallyTrulySetName(value)" instead of
"AutoGeneratedTable.setName(self, value)".  Okay, not
reallyTrulySetName, but something like that.

Anyway, it still worked, but as I kept adding more features the builder
got more complicated -- never overwhelming, but I think from seeing this
that a metaclass could accomplish the same thing in a more elegant
fashion.  Especially since this is a small but essential piece of code
to much of my programming, I'm interested in keeping it tight -- I never
felt as comfortable with MiddleKit, which introduced a toolchain into my
code where otherwise I had none. 

  Ian






More information about the Python-list mailing list