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