Late initialization using __getattribute__

Bruno Desthuilliers bruno.42.desthuilliers at websiteburo.invalid
Thu Sep 4 10:23:43 CEST 2008


bukzor a écrit :
> On Sep 3, 1:02 pm, Bruno Desthuilliers
> <bdesth.quelquech... at free.quelquepart.fr> wrote:
>> bukzor a écrit :
>> (snip)
>>
>>> Thanks for the reply. Just to see it not work, I tried to remove
>>> __getattribute__ from LateInitMixIn, but couldn't get it to work.
>> ??? Sorry, I don't get what you mean...
> 
> Since you said __getattribute__ is an attribute of the class, I tried
> to run (something to the effect of) delattr(self.__class__,
> "__getattribute__"),

Ah, ok. Definitively *not* a thing to do...


> but it threw an AttributeError.

You'd have to call it on the mixin class itself, not on a subclass.

> 
>>> My Base class is a C class (_mysql.connection from MySQLdb) that
>>> sometimes segfaults if you try to use it before it's fully
>>> initialized,
>>
>> ... I have used MySQLdb for years on more than a dozen linux
>> distribs, and never had such a problem. Is this a known bug ? Or is
>> there something wrong with your setup ?
> 
> I'm trying to optimize my number of connections

Connection pooling anyone ? IIRC, this is something that already exists 
in quite a couple libs / frameworks. Is there a reason you try to roll 
your own ?

> by not fully
> initializing (read: not connecting) my connection until it's used in
> some way. Of course the maintainer didn't envision this (mis)use, so
> the object sometimes throws bad errors until it's fully initialized.

Ok.

> Of course the *correct* way to do this is to be more careful about
> when I create connections, but I think I should be able to get this to
> work, and it (would be) much easier to do it The Right Way once it
> works.

Please pardon me for repeating the same thing over and over, but messing 
with __getattribute__ is certainly not the way to go.

>>> so unfortunately I think I need to use __getattribute__
>>> to do this. I'm doing all this just to make the connection not
>>> actually connect until used.
>> I may be dumb, but I don't get how this is supposed to solve your
>> problem. But anyway : there's a known design pattern for what you're
>> trying to do, that doesn't require mixins nor messing with
>> __getattribute__ (which, I repeat, is more often than not something you
>> *don't* want to do). The name of the design pattern is "proxy". I
>> strongly suggest that you 1/ try to cure the real problem instead of
>> hacking around and 2/ read about the proxy design pattern.
>>
>> My 2 cents...
> 
> I like the idea of mix-ins, but can't figure out how to make a proxy
> work that way.

You mean, "how to use a proxy for lazy initialization" ? Heck, that's 
the exact use case in the GoF.

> For a long time I had a proxy class that added five or
> six features on top of the MySQLdb package, but it wasn't configurable
> enough, and I'm working on splitting each feature into its own MixIn
> class.
> 
> 
> As an aside, this is working for me pretty well. The "reconnect"
> method (inheritied from a "Reconnectable" mixin) uses several of the
> object's attributes, so I need to set _inited beforehand so that I
> don't get into an infinite __getattribute__ loop. What I'd *really*
> like to do is remove __getattribute__ from the object at that point.

You can't. Or, more exactly, all you can do is remove __getattribute__ 
from the mixin class - but then the mixin class won't work anymore. I 
don't mean to be condescendant, but it looks like you don't have a clear 
understanding of Python's object model here - else you wouldn't even 
consider doing such a thing. FWIW, I posted a solution based on the 
__getattr__ hook, which did work - at least for the "specs" implied by 
your code snippet.




More information about the Python-list mailing list