473,785 Members | 2,831 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Late initialization using __getattribute_ _

I want to make a MixIn class that waits to initialize its super-
classes until an attribute of the object is accessed. Not generally
useful, but desirable in my case. I've written this, and it works, but
would like to take any suggestions you guys have. I've commented out
the "delattr" call because it throws an AttributeError (although I
don't know why).

class LateInitMixIn(o bject):
def __init__(self):
print "LateInit initialization"
self.inited = False
def __getattribute_ _(self, attr):
print "Doing __getattribute_ _"
getattr = lambda attr:object.__g etattribute__(s elf, attr)
if not getattr("inited "):
super(LateInitM ixIn, self).__init__( )
setattr(self, "inited", True)
#delattr(self, "__getattribute __")
return getattr(attr)

class Base(object):
def __init__(self):
print "Base initialization"
self.base = True
class LateInit(LateIn itMixIn, Base): pass

def main():
S = LateInit()
print S
print
print "Should do Base init after now"
print S.base
print S.base

if __name__=="__ma in__": main()


This gives the following output:
LateInit initialization
<__main__.LateI nit object at 0x2a960c1c50>

Should do Base init after now
Doing __getattribute_ _
Base initialization
True
Doing __getattribute_ _
True
Sep 3 '08 #1
8 1779
On Sep 3, 12:19*pm, Bruno Desthuilliers
<bdesth.quelque ch...@free.quel quepart.frwrote :
bukzor a écrit :
I want to make a MixIn class that waits to initialize its super-
classes until an attribute of the object is accessed. Not generally
useful, but desirable in my case. I've written this, and it works, but
would like to take any suggestions you guys have.

You shouldn't mess with __getattribute_ _ unless you really know what
you're doing and are ok to suffer the constant performance hit you'll
get. Remember that __getattribute_ _ actually *is* the implementation of
attribute lookup rules, and is called on each and every attribute
lookup. Your below snippet would be much better using __getattr__ (which
is only called as a last resort).
I've commented out
the "delattr" call because it throws an AttributeError (although I
don't know why).

__getattribute_ _ belongs to the class, not to the instance. delattr()
only removes instance attributes. You'd have to remove __getattribute_ _
from the LateInitMixIn class object itself, but then it would break the
whole thing.
class LateInitMixIn(o bject):
* * def __init__(self):
* * * * print "LateInit initialization"
* * * * self.inited = False
* * def __getattribute_ _(self, attr):
* * * * print "Doing __getattribute_ _"
* * * * getattr = lambda attr:object.__g etattribute__(s elf, attr)
* * * * if not getattr("inited "):
* * * * * * super(LateInitM ixIn, self).__init__( )
* * * * * * setattr(self, "inited", True)
* * * * #delattr(self, "__getattribute __")
* * * * return getattr(attr)

Here's another possible implementation (which doesn't solve all
problems, cf below) using __getattr__:

class LateInitMixin(o bject):
* * *def __init__(self):
* * * * *print "not yet"
* * * * *self.__initial ized = False

* * *def __getattr__(sel f, name):
* * * * *if self.__initiali zed:
* * * * * * *raise AttributeError(
* * * * * * * * *"object %s has no attribute '%s'" % (type(self), name)
* * * * * * * * *)
* * * * *super(LateInit Mixin, self).__init__( )
* * * * *self.__initial ized = True
* * * * *return getattr(self, name)

class Base(object):
* * *def __init__(self):
* * * * *print "yet"
* * * * *self.base = True

class LateInit(LateIn itMixin, Base):
* * *pass

def main():
* * *print "shouldn't init"
* * *S = LateInit()
* * *print "should init"
* * *print S.base

if __name__=="__ma in__":
* * *main()

Ok, now, the other problem : what if Base.__init__ expects args ?
Thanks for the reply. Just to see it not work, I tried to remove
__getattribute_ _ from LateInitMixIn, but couldn't get it to work.

My Base class is a C class (_mysql.connect ion from MySQLdb) that
sometimes segfaults if you try to use it before it's fully
initialized, 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.
Sep 3 '08 #2
On Sep 3, 1:02*pm, Bruno Desthuilliers
<bdesth.quelque ch...@free.quel quepart.frwrote :
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 __"), but it threw an AttributeError.

>
My Base class is a C class (_mysql.connect ion 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 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
works.
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. 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 "Reconnecta ble" 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.
def __getattribute_ _(self, attr):
"connect if it would otherwise cause an error."
getattr = lambda attr:object.__g etattribute__(s elf, attr)

if not getattr("_inite d"):
print "connecting ."
setattr(self, "_inited", True)
getattr("reconn ect")()
return getattr(attr)
Thanks for your help,
--Buck
Sep 3 '08 #3
On Sep 4, 12:26*am, bukzor <workithar...@g mail.comwrote:
I'm trying to optimize my number of connections by not fully
initializing (read: not connecting) my connection until it's used in
some way.
I had the same use case and I solved with a simple property. Here is
the code
I have for pymssql:

@property
def conn(self):
if self._conn is None:
self._conn = _mssql.connect( self.host, self.user,self. passwd)

self._conn.sele ct_db(self.dbna me)
return self._conn

The connection is really instantiate only when you call self.conn to
perform the query, not when you instantiate the class.
Sep 4 '08 #4
bukzor a écrit :
On Sep 3, 1:02 pm, Bruno Desthuilliers
<bdesth.quelque ch...@free.quel quepart.frwrote :
>bukzor a écrit :
(snip)
>>Thanks for the reply. Just to see it not work, I tried to remove
__getattribut e__ 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.connect ion 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 "Reconnecta ble" 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.

Sep 4 '08 #5
>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.
I mean, "how to make a MixIn class that uses the proxy pattern". I'd
like to be able to do something like this:

class SuperCursor(Fea tureOneMixIn, FeatureTwoMixin , ...,
VanillaCursor): pass

This works with my current implementation. After thinking about it
more, I think I've got such a thing written. I had to use
inspect.getmro and new.classobj to do it, but it works and it honors
the usual mro (as far as I can tell). I've put the code at the bottom
to (try to) maintain readability.

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 "Reconnecta ble" 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.
My toy example turned out to be not the best representation of the
problem.
The base class has attributes that "exist" but either throw errors or
segfault
if used before reconnect() is called. This means that I need to
capture more than
just the attributes that would throw AttributeError.


#CODE########## ############### ###############
class Base(object):
def __init__(self, *args, **kwargs):
self.args = args
self.kwargs = kwargs
def __str__(self): return "<Base object created with %s %s>" %
(self.args, self.kwargs)

class MixIn2(object):
def __str__(self):
return "<MixIn2 with %s>" % super(MixIn2, self).__str__()

class MixIn1(object):
def __str__(self):
return "<MixIn1 with %s>" % super(MixIn1, self).__str__()

class ProxyMixIn(obje ct):
def __init__(self, *args, **kwargs):
self.__proxied = None
self.__args = args
self.__kwargs = kwargs
def __getattr__(sel f, attr):
print "Getting", attr
try: return getattr(self.__ proxied, attr)
except AttributeError:
if self.__proxied: raise
else:
from inspect import getmro
mro = getmro(self.__c lass__)
mro = mro[list(mro).index (ProxyMixIn) + 1:]
print "Proxied mro", mro
from new import classobj
self.__proxied = classobj("Proxi ed", mro, globals())
(*self.__args, **self.__kwargs )
return getattr(self.__ proxied, attr)
def __str__(self):
return "<Proxy of %s>" % super(ProxyMixI n, self).__str__()

class Proxy(MixIn1, ProxyMixIn, MixIn2, Base): pass

def main():
p = Proxy(1,2,3, one=1, two=2)
print p
main()

#OUTPUT######## ############### ###############
Getting args
Proxied mro (<class '__main__.MixIn 2'>, <class '__main__.Base' >, <type
'object'>)
Getting kwargs
<MixIn1 with <Proxy of <MixIn2 with <Base object created with (1, 2,
3) {'two': 2, 'one': 1}>>>>

Sep 4 '08 #6
On Sep 4, 12:36 pm, bukzor <workithar...@g mail.comwrote:
>>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.

I mean, "how to make a MixIn class that uses the proxy pattern".
You don't. That's not how proxies work.
I'd like to be able to do something like this:

class SuperCursor(Fea tureOneMixIn, FeatureTwoMixin , ...,
VanillaCursor): pass
Why does it have to look like that? A good programmer lets the code
look however it has to look to most effectively do it's job.

With a proxy, the "base class" isn't a base class but a member. Here
is a very simple example:

class SuperCursor(obj ect):
def __init__(self):
self._cursor = VanillaCursor()
self._connected = False
def __getattr__(sel f,attr):
if not self._connected :
self._cursor.co nnect()
self._connected = True
return getattr(self._c ursor,attr)

cursor = SuperCursor()

That doens't use a mixin, but why should it?

Carl Banks
Sep 4 '08 #7
I'd like to be able to do something like this:
class SuperCursor(Fea tureOneMixIn, FeatureTwoMixin , ...,
VanillaCursor): pass

Why does it have to look like that? *A good programmer lets the code
look however it has to look to most effectively do it's job.

With a proxy, the "base class" isn't a base class but a member. *Here
is a very simple example:

class SuperCursor(obj ect):
* * def __init__(self):
* * * * self._cursor = VanillaCursor()
* * * * self._connected = False
* * def __getattr__(sel f,attr):
* * * * if not self._connected :
* * * * * * self._cursor.co nnect()
* * * * * * self._connected = True
* * * * return getattr(self._c ursor,attr)

cursor = SuperCursor()

That doesn't use a mixin, but why should it?
The point of using a mixin is to not limit myself to inheriting from
VanillaCursor. I want to put this on top of various subclasses of the
vanilla cursor, like TimeLimitedCurs or or RetryingCursor. I have four
other mixins that operate this way, so it's desirable to keep this one
in line with that.
Sep 4 '08 #8
On Sep 4, 3:38 pm, bukzor <workithar...@g mail.comwrote:
The point of using a mixin is to not limit myself to inheriting from
VanillaCursor. I want to put this on top of various subclasses of the
vanilla cursor, like TimeLimitedCurs or or RetryingCursor. I have four
other mixins that operate this way, so it's desirable to keep this one
in line with that.
http://www.bartleby.com/59/3/foolishconsi.html

I think that desire is hurting you more than it's helping. It's fine
to be consistent for consistency's sake, but you are taking
consistency to an unhealthy extreme. A mixin is simply the wrong tool
to do this with.

My advice: either use a proxy, or manage your connections better.
Carl Banks
Sep 4 '08 #9

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
3639
by: Ruud de Jong | last post by:
I have the situation where I need to construct the name of a static method, and then retrieve the corresponding function from a class object. I thought I could just use __getattribute__ for this purpose. This works fine if I already have an instantiation of the class, but not when I try this on the class object directly. A bare bones example:
0
6604
by: Gigi | last post by:
Hi, In the Python documentation regarding __getattribute__ (more attribute access for new style classes) it is mentioned that if __getattribute__ is defined __getattr__ will never be called (unless called explicitely). Here is the exact citation: """ The following methods only apply to new-style classes. __getattribute__( self, name)
3
2579
by: Sylvain Ferriol | last post by:
hello when i define __getattribute__ in a class, it is for the class instances but if i want to have a __getattribute__ for class attributes how can i do that ? sylvain
5
2069
by: Stefan Sonnenberg-Carstens | last post by:
Hi there, I'm facing some strange things - but maybe only me is strange - anyway... i wrote the following code: +++ class T(object): def __init__(self,name='',port=80): self.name=name
5
2527
by: Barry Kelly | last post by:
I'm running this version of Python: Python 2.4.3 (#1, May 18 2006, 07:40:45) on cygwin I read in the documentation that these two expressions are interchangeable: x.__getattribute__('name') <==> x.name
4
3324
by: Pedro Werneck | last post by:
Hi all I noticed something strange here while explaining decorators to someone. Not any real use code, but I think it's worth mentioning. When I access a class attribute, on a class with a custom metaclass with a __getattribute__ method, the method is used when acessing some attribute directly with the class object, but not when you do it from the instance.
1
5740
bartonc
by: bartonc | last post by:
Still have to prepend "default" when assigning variables to this class, but it now allows val = inst.vaule:"""Encapuslate a Default Values Object and Config File""" from inspect import getmembers import wx class DefaultValueHolder(object): """Intended for use with wxConfig (or maybe _winreg) to set up and/or get registry key names and values. Name attrs as default*. "default" will be stripped of when reading and...
6
3557
by: Adam Donahue | last post by:
As an exercise I'm attempting to write a metaclass that causes an exception to be thrown whenever a user tries to access 'attributes' (in the traditional sense) via a direct reference. Consider: class X( object ): y = 'private value' def get_y( self ): return self.y
15
1791
by: r0g | last post by:
Hi There, I know you can use eval to dynamically generate the name of a function you may want to call. Can it (or some equivalent method) also be used to do the same thing for the variables of a class e.g. class Foo(): bar = 1 gum = 2
0
9480
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
1
10090
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9949
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8971
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7499
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
6739
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5511
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4050
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
2879
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.