Who am I: can a class instance determine its own name?
Emile van Sebille
emile at fenx.com
Thu Mar 8 16:45:04 EST 2001
Now that you know exactly why you shouldn't,
class Bar:
pass
class Foo:
" container class for Bars "
def __init__(self):
self.barList = []
def addBar(self, bar):
import traceback
from string import split
callingCode = traceback.extract_stack()[-2][3]
name = split(split(callingCode, 'addBar(')[1],
')')[0]
self.barList.append(name)
def listBars(self):
return self.barList
if __name__ == '__main__':
Foo_One = Foo()
Foo_Two = Foo()
Bar_A = Bar()
Bar_B = Bar()
Foo_One.addBar(Bar_A)
Foo_One.addBar(Bar_B)
Foo_Two.addBar(Bar_B)
print Foo_One.listBars()
#...returns a sequence of Bar instance names:
['Bar_A','Bar_B']
print Foo_Two.listBars()
# returns a sequence of Bar instance names: ['Bar_B']
use-at-your-own-risk-ly y'rs
--
Emile van Sebille
emile at fenx.com
-------------------
"Tim Churches" <tchur at optushome.com.au> wrote in message
news:mailman.984081385.20244.python-list at python.org...
> Thanks to Gregory Jorgensen, Jeremy Reed, Steve Purcell,
Steve Holden,
> Matthias Oberlander, Daniel Klein and Remco Gerlich for
responding to my
> question: can a class instance determine the name of the
variable which
> refers to it? The answer appears to be "no, it can't". A
number of
> respondents pointed out that multiple variables may all
refer to the
> same class instance, so my question should have been: "can
a class
> instance determine the name(s) of the variable(s) which
refer(s) to
> it?". The answer is still no, and that the solution is to
explicitly
> assign each instance a name attribute at instantiation.
>
> A number of people asked why I needed to know. Consider
the problem of
> composition. You define a container class Foo which can
contain many
> instances of the Bar class, which are added to Foo with
the addBar
> method.
>
> ######################################
> Foo_One = Foo(name="Foo_One")
> Foo_Two = Foo(name="Foo_Two")
>
> Bar_A = Bar(name="Bar_A")
> Bar_B = Bar(Name="Bar_B")
>
> Foo_One.addBar(Bar_A)
> Foo_One.addBar(Bar_B)
>
> Foo_Two.addBar(Bar_B)
>
> Foo_One.listBars()
> ...returns a sequence of Bar instance names:
['Bar_A','Bar_B']
> Foo_Two.listBars()
> ...returns a sequence of Bar instance names: ['Bar_B']
> ######################################
>
> I was just trying to avoid the inelegant redundancy of
having to name
> each Bar instance twice - once when specifying the name of
the variable
> which refers to the Bar instance, and once as an attribute
of that
> instance (the use of a keyword parameter to __init__ to
specify the name
> is just for clarity).
>
> What I was aiming at was this sort of functionality:
>
> ######################################
> Foo_One = Foo(name="Foo_One")
> Foo_Two = Foo(name="Foo_Two")
>
> Bar_A = Bar()
> Bar_B = Bar()
>
> Foo_One.addBar(Bar_A)
> Foo_One.addBar(Bar_B)
>
> Foo_Two.addBar(Bar_B)
>
> Foo_One.listBars()
> ...returns a sequence of Bar instance names:
['Bar_A','Bar_B']
> Foo_Two.listBars()
> ...returns a sequence of Bar instance names: ['Bar_B']
> ######################################
>
> One solution would be:
>
> ######################################
> Foo_One = Foo(name="Foo_One")
> Foo_Two = Foo(name="Foo_Two")
>
> Foo_One.addBar(Bar(name="Bar_A"))
> Foo_One.addBar(Bar(name="Bar_B"))
>
> Foo_Two.addBar(Bar(name="Bar_B"))
>
> Foo_One.listBars()
> ...returns a sequence of Bar instance names:
['Bar_A','Bar_B']
> Foo_Two.listBars()
> ...returns a sequence of Bar instance names: ['Bar_B']
> ######################################
>
> ...but that just creates a different form of redundancy...
>
> The solution I have settled on is to accept the minor
inelegance and
> move on to more important matters...
>
> Cheers,
>
> Tim C
>
More information about the Python-list
mailing list