2

There is a lot of confusion with python names in the web and documentation doesn't seem to be that clear about names. Below are several things I read about python names.

  1. names are references to objects (where are they? heap?) and what name holds is an address. (like Java).

  2. names in python are like C++ references ( int& b) which means that it is another alias for a memory location; i.e. for int a , a is a memory location. if int& b = a means that b is another name the for same memory location

  3. names are very similar to automatically dereferenced pointers variables in C.

Which of the above statements is/are correct?

Does Python names contain some kind of address in them or is it just a name to a memory location (like C++ & references)?

Where are python names stored, Stack or heap?

EDIT:

Check out the below lines from http://etutorials.org/Programming/Python.+Text+processing/Appendix+A.+A+Selective+and+Impressionistic+Short+Review+of+Python/A.2+Namespaces+and+Bindings/#

Whenever a (possibly qualified) name occurs on the right side of an assignment, or on a line by itself, the name is dereferenced to the object itself. If a name has not been bound inside some accessible scope, it cannot be dereferenced; attempting to do so raises a NameError exception. If the name is followed by left and right parentheses (possibly with comma-separated expressions between them), the object is invoked/called after it is dereferenced. Exactly what happens upon invocation can be controlled and overridden for Python objects; but in general, invoking a function or method runs some code, and invoking a class creates an instance. For example:

pkg.subpkg.func() # invoke a function from a namespace

x = y # deref 'y' and bind same object to 'x'

This makes sense.Just want to cross check how true it is.Comments and answers please

tez
  • 4,990
  • 12
  • 47
  • 67
  • And by names, you really mean variables. Does this [previous answer of mine](http://stackoverflow.com/questions/12080552/python-list-doesnt-reflect-variable-change-new-to-python/12080644#12080644) help understanding at all? – Martijn Pieters Sep 08 '12 at 09:34
  • Yeah by names I mean variable.But it was suggested not to use the word 'variables' in python. Don't exactly know why. – tez Sep 08 '12 at 09:54
  • I guess that not just variables can hold a reference to a python object, attributes on classes and instances, keys and values in dicts, indices in lists, etc. call all hold references too. – Martijn Pieters Sep 08 '12 at 09:58
  • @tez: on the "variables" issue, some people feel that it's easier to grok Python by thinking purely in terms of "objects", "names", and "namespaces". Those terms don't have as much baggage, and so it's easier to separate how Python works from how it "should" work based on C or C++, and stop trying to think of Python's object model as "C++ but with [something]", i.e. as another language but with some quirks. "Python doesn't have variables" is shorthand for this view, although even we use the word 'cause it's handy. Others (like Ned Batchelder 'round here) think that this isn't helpful. – DSM Sep 08 '12 at 13:20

3 Answers3

4

names are references to objects

Yes. You shouldn't care where the objects live if you just want to understand Python variables' semantics; they're somewhere in memory and Python implementations manage memory for you. How they do that depends on the implementation (CPython, Jython, PyPy...).

names in python are like C++ references

Not exactly. Reassigning a reference in C++ actually reassigns the memory location referenced, e.g. after

int i = 0;
int &r = i;
r = 1;

it is true that i == 1. You can't do this in Python except by using a mutable container object. The closest you can get to the C++ reference behavior is

i = [0]   # single-element list
r = i     # r is now another reference to the object referenced by i
r[0] = 1  # sets i[0]

are very similar to automatically dereferenced pointers variables in C

No, because then they'd be similar to C++ references in the above regard.

Does Python names contain some kind of address in them or is it just a name to a memory location?

The former is closer to the truth, assuming a straightforward implementation (again, PyPy might do things differently than CPython). In any case, Python variables are not storage locations, but rather labels/names for objects that may live anywhere in memory.

Every object in a Python process has an identity that can be obtained using the id function, which in CPython returns its memory address. You can check whether two variables (or expressions more generally) reference the same object by checking their id, or more directly by using is:

>>> i = [1, 2]
>>> j = i       # a new reference
>>> i is j      # same identity?
True
>>> j = [1, 2]  # a new list
>>> i == j      # same value?
True
>>> i is j      # same identity?
False
Fred Foo
  • 355,277
  • 75
  • 744
  • 836
  • 1
    @tez: that description is more or less right, at least up to and including the part about `NameError`. The rest of it has little to do with Python variables; appending `()` after *any* expression causes a function call to be tried. – Fred Foo Sep 08 '12 at 19:58
2

Python names are, well, names. You have objects and names, that's it.

Creating an object, say [3, 4, 5] creates an object somewhere on the heap. You don't need to know how. Now you can put names to target this object, by assigning it to names:

x = [3, 4, 5]

That is, the assignment operator assigns names rather than values. x isn't [3, 4, 5], no, it's simply a name pointing to the [3, 4, 5] object. So doing this:

x = 1

Doesn't change the original [3, 4, 5] object, instead it assigns the object 1 to the name x. Also note that most expressions like [3, 4, 5], but also 8 + 3 create temporaries. Unless you assign a name to that temporary it will immediately die. There is no (except, for example in CPython for small numbers, but that aside) mechanism to keep objects alive that aren't referenced, and cache them. For example, this fails:

>>> x = [3, 4, 5]
>>> x is [3, 4, 5] # must be some object, right? no!
False

However, that's merely assignment (which is not overloadable in Python). In fact, objects and names in Python very well behave like automatically dereferencing pointers, except that they are automatically reference counted and die after they're not referenced anymore (in CPython, at least) and that they do not automatically dereference on assignment.

Thanks to this memory model, for example the C++ way of overloading index operations doesn't work. Instead, Python uses __setitem__ and __getitem__ because you can't return anything that's "assignable". Furthermore, the operators +=, *=, etc... work by creating temporaries and assigning that temporary back to the name.

orlp
  • 112,504
  • 36
  • 218
  • 315
  • It's unfortunate that you use a mutable container in your example. Because `x` points to a list object, which in turn has 3 references that point to three different python int objects. So `x[0] = 1` changes the list object's first reference. And there are also cases where `x = ''; y = ''; x is y` is True (but those are CPython internals). – Martijn Pieters Sep 08 '12 at 09:56
  • 1
    @MartijnPieters: the fun part is that `x[0] = 1` isn't actually asignment. It's short for `x.__setitem__(0, 1)`. – orlp Sep 08 '12 at 10:05
  • And `x = 1` is (internally) the same as `locals().__setitem__('x', 1)`; and in a module that translates to `globals().__setitem__('x', 1)` as well, which *in turn* is an object in the `sys.modules` mapping... Of course, it's the C API, so no actual `__setitem__` is called, except when you pass in a custom mapping to `exec` or such tricks. – Martijn Pieters Sep 08 '12 at 10:07
  • So it is true that python names are automatically dereferenced pointers (except for assignments ofcourse ) ??????? – tez Sep 08 '12 at 10:21
1

Python objects are stored on a heap and are garbage collected via reference counting.

Variables are references to objects like in Java, and thus point 1 applies. I am not familiar with either C++ or automatically dereferenced pointer variables in C, to make a call on those.

Ultimately, it's the python interpreter that does the looking up of items in the interpreter structures, which usually are python lists and dictionaries and other such abstract containers; namespaces use dict (a hash table) for example, where the names and values are pointers to other python objects. These are managed explicitly by the mapping protocol.

To the python programmer, this is all hidden; you don't need to know where your objects live, just that they are still alive as long as you have something referencing them. You pass around these references when coding in python.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • 1
    (1) That it internally uses reference counting is mostly irrelevant even when it's true. And it's not even entirely true on CPython. (2) As others have explained, Python has nothing like C++ references. -1 –  Sep 08 '12 at 09:44
  • I appreciate the correction, but honestly I don't consider this answer useful enough (for this specific context) to remove my downvote. –  Sep 08 '12 at 09:47
  • @delnan: I realized I had some assumptions about C++ pointers that I cannot justify, so I corrected that sentence. Sorry you don't find it useful. – Martijn Pieters Sep 08 '12 at 09:48
  • The thing is, while much of what you state is true (and important in some contexts), it does not really relate to the Python execution model, or to the semantics of variables/names in Python programs. You seem to focus on implementation details, and I consider that uncalled for. –  Sep 08 '12 at 09:49
  • @delnan: perhaps; the OP is approaching this from a C, C++ and Java perspective though, so presumably he has some understanding of those contexts. I find the internals very interesting myself, and it helps my own understanding. Just a different perspective, perhaps. – Martijn Pieters Sep 08 '12 at 09:52
  • @delnan: In retrospect, it's the 'stack or heap' part of the OP that made me delve into the internals. – Martijn Pieters Sep 08 '12 at 10:01