finding the parent class (not superclass) of the currently executing method derived from a Borg class

Bruno Desthuilliers bruno.42.desthuilliers at websiteburo.invalid
Tue Sep 9 10:35:11 CEST 2008


seanacais a écrit :
> I want to create a class derived from a Borg class that can
> instantiated as part of a script or be contained in other classes.
> When methods from the Borg class are called, I would  like to know the
> name of the class that contains the Borg class.


> I've played a bit with inspect and _getframe from the sys module but
> get inconsistent results.  The main problem is if the Borg class is
> instantiated outside a containing class, then I need to go up a
> different number of stack frames.  But this information isn't
> available till after I've run out of stack frames.

The simplest solution is usually the better : explicitely pass the 
caller (whether instance or module or whatever you want)


> Hopefully the following code better describes what I'm looking to do.
> 
> import sys
> 
> class Borg:
>     _shared_state = {}
>     def __init__(self):
>         self.__dict__=self._shared_state
> 
> class Assimilated(Borg):
>     valueByCaller = {}

You understand that, being a class attribute, valueByCaller won't be 
part of the Borg's _shared_state ?

>     def __init__(self, setupvalue):
>         print "In Assimilated.__init__()"
>         print "setupvalue is: " + str(setupvalue)
> 
>         # would like  key to  be name of class (or module) that
>         # contins Assimilated
>         callerID =  sys._getframe(1).f_code.co_name
> 
>         self.valueByCaller[callerID] =  setupvalue
> 
>         print self.valueByCaller

Anyway, since you override __init__ and don't call Borg.__init__, your 
Assimilated class doesn't behave as a Borg.

(snip)


> 
> When I run this, I get the following output:
> 
> In Assimilated.__init__()
> setupvalue is: 2
> {'A': 2}
> In Assimilated.__init__()
> setupvalue is: 3
> {'A': 2, 'B': 3}
> In Assimilated.__init__()
> setupvalue is: 4
> {'A': 2, 'C': 4, 'B': 3}
 >
(snip)
> 
> What I found most peculiar when I started this was that the
> valueByCaller dictionary was completely populated before the __init__
> method of a was executed. 

Indeed. In classes A, B and C, assim_object is class attribute - so it 
is instanciated when the class statement is executed.

> I'm pretty sure that this has to do with
> the difference between when the object gets instanced and when it gets
> initialized,

Not at all. It has to do with the fact that all statements within a 
class block are executed before the class statement itself is executed. 
And since your class statements are at the top-level, they are executed 
when the module is initialised (that is, passed to the python runtime or 
first imported).

> but I need to do some more research and reading to be
> able to explain it to myself.

Indeed. May I suggest that you *learn* Python's object model and 
Python's execution model instead of assuming anything ? This will save 
you a whole lot of time and frustration !-)



More information about the Python-list mailing list