[Tutor] A deeper explanation of ability to modify list elements in-place

Steven D'Aprano steve at pearwood.info
Fri Nov 12 00:35:32 CET 2010


Serdar Tumgoren wrote:

>> In Python, if you have x[0] = Dummy(), the list object x stores the Dummy
>> instance itself.
> 
> 
> I think the above example gets to the source of my confusion. Clearly the
> instance remains accessible via x[0], but I somehow never thought of a
> specific list index as an obvious "symbol" for -- or reference to -- an
> instance.

Yes, that's it -- objects can be referenced by *any* , er, reference in 
any other object. Unfortunately, I'm not aware of any useful synonym for 
"reference", to distinguish the Python-specific idea of a reference to 
an object from the plain English meaning of reference, which makes it a 
little confusing to talk about these things.

Named variables are not the only references: you can create anonymous 
objects inside lists, dicts or sets, or pass instances directly to a 
function (where of course they get given a name), or by a closure:

class Dummy:
     def __init__(self):
         print("created %s" % self)
     def __del__(self):
         print("deleted %s" % self)


def func():
     x = Dummy()
     def inner():
         return x
     return inner

f = func()
del Dummy, func


Despite both the class and func being deleted, the instance x remains 
alive so long as the inner function remains alive.



 > I suspect that my confusion stems from the day-to-day routine of
> instantiating an object and assigning it to a variable at the same time,
> often inside a loop, and then performing additional processing on this
> instance *before* storing it in a list or some other container.

Of course binding objects to names is a very common use, but it's hardly 
the only one.


> Above, it seems that you're *still* performing simultaneous instantiation
> and assignment (from a code perspective), but the "symbol" that you're
> assigning to is the list index itself.

Not to the index, which would be 0, 1, 2, ... but to the list item.


> And that seems to explain why the Dummy instance remains accessible and is
> not garbage-collected. Is that a correct understanding?


Yes, you've got it!


[...]

>> There is no way to get access to the underlying pointers from pure Python
>> code. From pure Python, pointers don't exist -- Python gives you no way to
>> create or access pointers from Python code. All you have access to is
>> objects.
> 
> 
> So is a reference simply a Python-level symbol (ie some collections of
> characters accessible from Python code) that corresponds to a pointer, which
> in turn points to the location in memory where the object is stored?

Now you're digging deep into the implementation... at *some level*, some 
piece of code must know where in memory the object itself lies. But that 
level is not Python code.

It's hard to talk about these things without confusion. There are 
various levels: symbols like "x[1]" or "name.attribute" exist in source 
code. Another level is the byte-code, which has its own symbols for 
referring to objects. A third level is the implementation ("under the 
hood") of the language. In the CPython implementation, a reference will 
be a pointer to a chunk of memory (the object). But of course other 
implementations, such as PyPy, IronPython, Jython and many others may 
choose different implementations. But at the top level, no, Python has 
no idea about the memory location of objects.

It is true that CPython uses memory locations for the ID of objects, but 
that's just a label, you can't do anything with it -- you can't take an 
address and fetch the object at that address, for instance. And other 
implementations make other choices: Jython and (I think) IronPython 
number objects sequentially 1, 2, 3, 4, ... as they are created, and use 
that as the unique ID, rather than the memory address.


-- 
Steven


More information about the Tutor mailing list