4.14. Object Identity

4.14.1. Identity

  • id() will change every time you execute script

  • An integer which is guaranteed to be unique and constant for this object during its lifetime

  • Two objects with non-overlapping lifetimes may have the same id() value.

  • In CPython it's also the memory address of the corresponding C object

Listing 4.93. Note, that id() will change every time you execute script
id('Watney')
# 4499664048

hex(id('Watney'))
# '0x10c336cb0'

4.14.2. String interning

  • https://en.wikipedia.org/wiki/String_interning

  • Method of storing only one copy of each distinct string value, which must be immutable

  • many high level languages use it

  • string literals and values are internally kept in a hashed list called 'string intern pool' and those which are identical are rendered as references to the same object

  • possible because str are immutable

  • implementation dependent

  • Jython, IronPython, PyPy and others may intern more aggressively

  • Calling the intern() function on strings will "force" a string to have the same object identity as any equivalent and previously interned string

Listing 4.94. CPython 3.7.4
('a' * 4096) is ('a' * 4096)
# True

('a' * 4097) is ('a' * 4097)
# False

4.14.3. is

  • is checks for object identity

  • is tests for identity, not equality

  • Compares id() output for both objects

  • CPython: compares the memory address a object resides in

  • Is used for checking if None

  • Testing strings with is only works when the strings are interned

4.14.3.1. Test if empty

if name is None:
    print('Your name is empty')
else:
    print(f'Hello {name}')

4.14.3.2. Test if value is equal

Changed in version Python: 3.8 Compiler produces a SyntaxWarning when identity checks (is and is not) are used with certain types of literals (e.g. str, int). These can often work by accident in CPython, but are not guaranteed by the language spec. The warning advises users to use equality tests (== and !=) instead.

Listing 4.95. Bad
 if name is 'Mark Watney':
    print('You are Space Pirate!')
 else:
    print('You are just a regular astronaut...')
Listing 4.96. Good
 if name == 'Mark Watney':
    print('You are Space Pirate!')
 else:
    print('You are just a regular astronaut...')

4.14.3.3. Using is in script

  • both objects has the same id.

a = 'Jan Twardowski'
b = 'Jan Twardowski'
print('==', a == b)
print('is', a is b)

print('id(a)', id(a))
print('id(b)', id(b))

print('memory(a)', hex(id(a)))
print('memory(b)', hex(id(b)))

print('hash(a)', hash(a))
print('hash(b)', hash(b))
== True
is False
id(a) 4851919024
id(b) 4851920112
memory(a) 0x1213268b0
memory(b) 0x121326cf0
hash(a) 2589808896583376772
hash(b) 2589808896583376772

4.14.3.4. Using is in REPL (evaluated line by line)

a = 'Jan Twardowski'
b = 'Jan Twardowski'
print('==', a == b)
print('is', a is b)

print('id(a)', id(a))
print('id(b)', id(b))

print('memory(a)', hex(id(a)))
print('memory(b)', hex(id(b)))

print('hash(a)', hash(a))
print('hash(b)', hash(b))
== True
is True
id(a) 4814965616
id(b) 4814965616
memory(a) 0x11efe8b70
memory(b) 0x11efe8b70
hash(a) -65752624953756666
hash(b) -65752624953756666

4.14.3.5. Using is in REPL (evaluated at once)

a = 'Jan Twardowski'
b = 'Jan Twardowski'
print('==', a == b)
print('is', a is b)

print('id(a)', id(a))
print('id(b)', id(b))

print('memory(a)', hex(id(a)))
print('memory(b)', hex(id(b)))

print('hash(a)', hash(a))
print('hash(b)', hash(b))
== True
is False
id(a) 4851919024
id(b) 4851920112
memory(a) 0x1213268b0
memory(b) 0x121326cf0
hash(a) 2589808896583376772
hash(b) 2589808896583376772

4.14.4. Assignments

Todo

Create Assignments