Accessing an instance via its memory address (instance at ...)

Bengt Richter bokr at oz.net
Sat Nov 13 19:34:32 CET 2004


On Fri, 12 Nov 2004 14:59:54 +0100, <simon.alexandre at cetic.be> wrote:

>Hi
>
>I have a list containing several instance address, for example:
>
>[<JavaClass instance at 00BAC290>, <JavaClass instance at 00BB0D10>,
><JavaClass instance at 00BA5230>]
                        ^^^^^^^^--[1]
[1] Is that what you mean by instance address? While that is an actual
hex representation of a memory address in some implementations, the purpose
of the number is identification, not access. What you have in the list is
actually a sequence of references to object representations. In python all
objects are accessed via these references, which internally may be pointers
or indices into storage or composite handles or whatever -- that is up to the
implementation. But when you write source code selecting such a reference, as
in my_list[2] selecting the 3rd (indexing from 0) reference in a list, that
accomplishes access to the object, and you can then write a trailing expression
like .foo() to call a foo method or .foo could be a non-method attribute, or
your selected reference might be to another list, in which case you could
add a trailing [123] to select from that list. Examples just mentioned
spelled out:
    my_list[2].foo()
    my_list[2].foo
    my_list[2][123]

>
>I'd like to invoke a method on each of these instance but I don't know :
>
>1. if its possible
>2. how to proceed
>
others have already demonstrated several ways, I just wanted to elaborate
on the concept of references vs the objects they refer to. Note that assignment
in python works with these object references too, so that when you write
    a = my_list[2]
    b = a
you have bound both names to the same object that my_list[2] refers to.
>someone can help me ?

Example of above things:

 >>> class A(object):
 ...     def foo(self): return '--> This is an instance of class A with id 0x%08X'%id(self)
 ...
 >>> my_list = [A() for dummy in range(2)]
 >>> my_list
 [<__main__.A object at 0x009011B0>, <__main__.A object at 0x009011F0>]

That looks similar to your list of objects. We can select one of them:

 >>> my_list[1]
 <__main__.A object at 0x009011F0>

And call the foo method by adding .foo() to the aforegoing expression:
 >>> my_list[1].foo()
 '--> This is an instance of class A with id 0x009011F0'

Same for the other one:
 >>> my_list[0].foo()
 '--> This is an instance of class A with id 0x009011B0'

If we don't tack on the parentheses we get the bound method (how
that happens -- i.e. the automatic binding together of a class instance
and a method of the class to make a bound method -- is central to how
python's classes work, and something you will want to understand).

 >>> my_list[0].foo
 <bound method A.foo of <__main__.A object at 0x009011B0>>

We can iterate through the list, which successively binds each object
to the supplied name (obj here) via the reference from the list:
 >>> for obj in my_list: print obj.foo()
 ...
 --> This is an instance of class A with id 0x009011B0
 --> This is an instance of class A with id 0x009011F0
 >>>

And show both together:
 >>> for obj in my_list: print obj, obj.foo()
 ...
 <__main__.A object at 0x009011B0> --> This is an instance of class A with id 0x009011B0
 <__main__.A object at 0x009011F0> --> This is an instance of class A with id 0x009011F0

BTW, that first part is just the standard representation of object instances in text,
and you can customize it via the __repr__ method, e.g.,

 >>> class A(object):
 ...     def foo(self): return '--> This is an instance of class A with id 0x%08X'%id(self)
 ...     def __repr__(self): return '<<My "A" instance at %x>>'%id(self)
 ...
 >>> my_list = [A() for dummy in range(2)]
 >>> my_list
 [<<My "A" instance at 9015f0>>, <<My "A" instance at 9011f0>>]
 >>> my_list[1]
 <<My "A" instance at 9011f0>>
 >>> my_list[1].foo()
 '--> This is an instance of class A with id 0x009011F0'
 >>> for obj in my_list: print obj, obj.foo()
 ...
 <<My "A" instance at 9015f0>> --> This is an instance of class A with id 0x009015F0
 <<My "A" instance at 9011f0>> --> This is an instance of class A with id 0x009011F0

We can still get the old style representation by explicitly calling the base __repr__
function we overrode:

 >>> for obj in my_list: print obj, object.__repr__(obj)
 ...
 <<My "A" instance at 9015f0>> <__main__.A object at 0x009015F0>
 <<My "A" instance at 9011f0>> <__main__.A object at 0x009011F0>
 >>>

But note that the builtin repr function uses our custom repr as one would expect:

 >>> my_list[1]
 <<My "A" instance at 9011f0>>
 >>> repr(my_list[1])
 '<<My "A" instance at 9011f0>>'

(The quotes are because interactively we are being shown that the result is a string,
whereas the plain expression uses repr to get a string to print interactively, which
prints the string plain). E.g.,

 >>> print repr(my_list[1])
 <<My "A" instance at 9011f0>>

I encourage you and others to explore interactively, and when you get something you
don't understand, copy from the screen and paste it into your posted question
(which you apparently did with the list snippet -- bravo ;-)

HTH

Regards,
Bengt Richter



More information about the Python-list mailing list