Created
April 20, 2012 19:52
-
-
Save beala/2431331 to your computer and use it in GitHub Desktop.
The weird behavior of Python's id() function.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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