Skip to content

Instantly share code, notes, and snippets.

@beala
Created April 20, 2012 19:52
Show Gist options
  • Save beala/2431331 to your computer and use it in GitHub Desktop.
Save beala/2431331 to your computer and use it in GitHub Desktop.
The weird behavior of Python's id() function.
import gc
import inspect
gc.disable()
test_counter = 0
def print_test_msg(message):
global test_counter
test_counter += 1
print "%d. %s Line: %d" % (test_counter, message, inspect.currentframe().f_back.f_lineno)
print_test_msg("Do two equal constants have the same id?")
print id("ab") == id("ab")
print_test_msg("Do two equal constants have the same id? These are longer constants than the previous test.")
print id("ab ab abab") == id("ab ab abab")
print_test_msg("Sanity check: Do two UNequal constants have the same id?")
print id("a") == id("b")
print_test_msg("Assign equal constants to different names. Do they have the same id?")
str_a = "cc cc"
str_b = "cc cc"
print id(str_a) == id(str_b)
print_test_msg("Do 'd'+'c' and the constant 'dc' have the same id?")
idconab = id("d"+"c")
idab = id("dc")
print idconab == idab
print_test_msg("First assign 'e' to `str_a`, and assign 'f' to `str_b`. Do `str_a+str_b` and 'ef' have the same id?")
str_a = "e"
str_b = "f"
print id("ef") == id(str_a+str_b)
# Custom string class
class MyStr(str):
def __new__(cls, v):
print "Creating a new MyStr..."
return super(MyStr, cls).__new__(cls,v)
print_test_msg("What is the type of an object created from our custom str class (MyStr)?")
print type(MyStr(""))
print_test_msg("What is the type of two MyStr's concatenated?")
print type(MyStr("l")+MyStr("l"))
print_test_msg("What is the type of a string created by directly calling str's __new__?")
print type(str.__new__(str, "a"))
print_test_msg("Do two MyStr objects with the same payload have the same id?")
print id(MyStr("g")) == id(MyStr("g"))
print_test_msg("Are they the same thing (test with 'is' operator)?")
print MyStr("h") is MyStr("h")
print_test_msg("Assign two MyStr objects with the same payload to two different variables. Do they have the same id?")
ms1 = MyStr("i")
ms2 = MyStr("i")
print id(ms1) == id(ms2)
# Custom string class, now with IDs that automatically increment
class MyStrId(str):
id = 0
def __new__(cls, v):
print "Creating a new MyStrId..."
newObj = super(MyStrId, cls).__new__(cls,v)
newObj.id = MyStrId.id
MyStrId.id += 1
return newObj
print "Our custom string class (MyStrId) now has an incrementing id attribute."
print_test_msg("Do two MyStrId's with the same payload have the same id?")
print id(MyStrId("j")) == id(MyStrId("j"))
print_test_msg("Do two MyStrId's with a DIFFERENT payload have the same id?")
print id(MyStrId("i")) == id(MyStrId("g"))
print_test_msg("Sanity check: Are their ID *attributes* different?")
print MyStrId("j").id != MyStrId("j").id
print_test_msg("Do two MyStrId's with the same payload, but assigned to different variables have the same id?")
ms3 = MyStrId("k")
ms4 = MyStrId("k")
print id(ms3) == id(ms4)
print_test_msg("Do the str 'ab' and the MyStrId 'ab' have the same id?")
print id('ab') == id(MyStrId('ab'))
print_test_msg("Do the str 'ab' and the MyStr 'ab' have the same id?")
print id('ab') == id(MyStr('ab'))
print_test_msg("Let's replace __builtins__.str with MyStrId. What's the type of a constant str?")
__builtins__.str = MyStrId
print type("a")
print_test_msg("Do str constants have an id attribute now? A message will be printed if MyStrId's constructor gets called.")
print hasattr("a", "id")
print_test_msg("What's the type of 'str'?")
print type(str)
print_test_msg("What's the type of '__builtins__.str'?")
print type(__builtins__.str)
print_test_msg("What's the type of MyStrId? ")
print type(MyStrId)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment