I was playing around with sys.getrefcount in Python 3.7 on Windows. I tried the following:
>>> import sys
>>> x = "this is an arbitrary string"
>>> sys.getrefcount(x)
2
I understand that one of the references is x, and the other is the parameter used internally within sys.getrefcount. This seems to work no matter the type to which x is initialized. However, I noticed some weird behavior when I don't assign before I pass:
>>> import sys
>>> sys.getrefcount("arbitrary string")
2
>>> sys.getrefcount(1122334455)
2
>>> sys.getrefcount(1122334455+1)
2
>>> sys.getrefcount(frozenset())
2
>>> sys.getrefcount(set())
1
>>> sys.getrefcount(object())
1
>>> sys.getrefcount([])
1
>>> sys.getrefcount(lambda x: x)
1
>>> sys.getrefcount(range(1122334455))
1
>>> sys.getrefcount(dict())
1
>>> sys.getrefcount(())
8341
>>> sys.getrefcount(tuple())
8340
>>> sys.getrefcount(list("arbitrary string"))
1
>>> sys.getrefcount(tuple("arbitrary string"))
1
>>> sys.getrefcount(("a", "r", "b", "i", "t", "r", "a", "r", "y", " ", "s", "t", "r", "i", "n", "g"))
2
What is going on here? It seems that immutable types have two references but mutable types have only one? Why does it seem that some objects assigned before being passed, while others only ever have a reference as a parameter?
Does this have something to do with str/int/tuple internment?
Edit: A more directed question: Why was it chosen that immutable types like frozenset() have a reference upon construction, while mutable types like set() does not? I understand in isolation why you might choose to keep this global-scope reference or not across the board, but why the discrepancy?