Late initialization using __getattribute__
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 :
>>> 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__,
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
>> ... 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.
> 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
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
> 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