1

Theory question

Every Python shell has objects that can be used without being declared or created, such as True, False, "", [], {}, and any combination of integers and floating point numbers.

This means that at any point, you can get their ids.

id(1)
id(42)
id('')

etc.

Of course, if you try to get the id of an undeclared object, you get:

id(myobject1)

Traceback (most recent call last):
  File "<pyshell#29>", line 1, in <module>
    id(myobject1)
NameError: name 'myobject1' is not defined

Since myobject1 points to nothing, it's not defined, and has no id.

Yet, there are an infinite number of objects which could be used without declaration, because the number system is infinite. Thus it would be impossible for all of the undeclared objects to have id's prior to being used in some capacity in the program.

When do these objects get assigned ids?

Ben Mordecai
  • 685
  • 2
  • 8
  • 19

3 Answers3

2

You are misunderstanding the concept of assignment.

On an assignment, you bind a object to a name. All names which are assigned to can be used in any way that is wanted, unassigned names don't exist and thus cannot point to anything (including "nowhere").

With id(spam) you ask for the object which spampoints to and then ask for its ID.

A non-existing name spam has no object assigned to it whose ID could be queried.

OTOH, every object has an ID.

glglgl
  • 89,107
  • 13
  • 149
  • 217
  • Ok, so an undeclared "object" (which is really no object at all) is a nonexistant pointer which has yet to be bound to an object. But what about objects like 42, which have id's? At what point is that id "generated" for lack of a better term? It's first use? – Ben Mordecai Dec 13 '12 at 15:49
  • 1
    I think the last conceptual leap here is that for builtin types, at least in the context of this question, the literal value can be thought of as a syntactical shorthand for instantiation and assignment. Thus saying `42` is somewhat like `42 = int(42)`. Following from that, `id(42)` can be thought of as `id(int(42))`. – Silas Ray Dec 13 '12 at 15:50
  • 1
    @BenMordecai The creation of an object. I can get the ID of an object without keeping it. With `id(object())` you create an object, get its ID and discard it immediately. `1`, `42`, `''` are either created as you use them (or as the function they live in is called), but afterwards they are kept as they are singletons. – glglgl Dec 13 '12 at 15:51
  • 'an undeclared "object" (which is really no object at all) is a nonexistant pointer which has yet to be bound to an object' - No. An undeclared object is not an object. It is an unbound name. As it has no object behind it, there is no ID which can be queried. – glglgl Dec 13 '12 at 15:52
  • 2
    String literals and integers are not singletons. The interpreter caches some of them (by default, numbers between -5 and 256 in CPython if memory serves), so `id(1) == id(1)`, but `id(49752) != id(49752)`. – Silas Ray Dec 13 '12 at 15:53
  • @sr2222 Ouch, you are right. I stand myself corrected. In a function, however, `id(49152) == id(49152)` should be true, or not? – glglgl Dec 13 '12 at 15:57
  • With `def f(): id(123123123) == id(123123123)`, `dis.dis(f)` refers to `LOAD_CONST 1 (123123123)` twice. If I do `f.func_code.co_consts`, I get `(None, 123123123)`, which should enable me to say that the both `123123123` are always the same. At the CLI level, you are right, however. – glglgl Dec 13 '12 at 16:00
  • I think the outcome of that would be undefined and implementation specific to a given interpreter. At least in 2.7 CPython on Windows, `id(49752) == id(49752)`, `a = 49752` `b = a` `id(b) == id(a)`, but `a = 49752` `b = 49752` `id(a) != id(b)`. – Silas Ray Dec 13 '12 at 16:01
  • @sr2222 In a function as well? – glglgl Dec 13 '12 at 16:02
  • @sr2222 Wow, that's actually pretty illuminating. `>>> id(2983) 22265772 >>> id(2983) 22265796 >>> id(2983)==id(2983) True` – Ben Mordecai Dec 13 '12 at 16:02
  • @glglgl, Hmm, you are right, in a function, again, at least in my interpreter, the ids do match up in all 3 cases. Sounds like a dangerous thing to rely on though. – Silas Ray Dec 13 '12 at 16:05
  • 1
    Yeah, that's just optimization. – Lennart Regebro Dec 13 '12 at 16:09
2

I'll try to counter the misconceptions one by one. That may or may not be useful.

Every Python shell has objects that can be used without being declared

There is no concept of "declaring" objects in Python. Objects therefore are neither declared nor undeclared.

or created

You can not use an object that is not created. All objects that exist have ids.

True, False

True and False are objects that exist. They have ids.

"", [], {}, and any combination of integers and floating point numbers.

Literals become objects when the code is executed. The combination of characters {} is in essence a shortcut for saying dict(). The objects created have ids.

Of course, if you try to get the id of an undeclared object, you get NameError.

No. NameError is when you are trying to use a name that has not been defined.

Since myobject1 points to nothing

Wrong, it does not "point to nothing". It hasn't been defined. It can't point to nothing, it doesn't exist.

and has no id.

Names do not have ids. Objects have ids. When you say

>>> foo = 5
>>> id(foo)
137396064

You are not asking for the id of the name foo. You are asking for the id of the object that the name foo as been assigned to. If you now reassign foo, you get another id:

>>> bar = foo
>>> foo = "string"
>>> id(foo)
3075254336
>>> id(bar)
137396064

The id of the objects stay the same, the names have been reassigned.

Yet, there are an infinite number of objects which could be used without declaration

No, they are not.

Lennart Regebro
  • 167,292
  • 41
  • 224
  • 251
  • 1
    That's an answer that deserves to be upvoted 300 times. You're someone who really knows his subject, not the case of everybody.... – eyquem Dec 13 '12 at 16:31
0

For your question on when 42 becomes an id assigned: You can think of 42 being int(42). It allocates memory for an integer that is of the value 42. After the integer was constructed, it is passed to the id() function. After that, the reference count of the integer is decremented and therefore deallocated.

Technically, the id of an object is nothing else but its address in memory.

Niklas R
  • 16,299
  • 28
  • 108
  • 203