2

Introduction

So I'm trying to follow this tutorial on RealPython: link. I struggle to understand the part about defensive copying. I've replicated the source of my confusion in my own code below.

My question is – why is the IDs different in the a.lst_different_name is not a.lst_different_name statement when using the same object (why does this statement evaluate to True)? And why is the ID altered for the same object after invoking this comparison (see output)?

Code

class TestClass:
    def __init__(self):
        self.__lst = [1, 2, 3]
    
    @property
    def lst_different_name(self):
        return self.__lst.copy()

a = TestClass()

print(a.lst_different_name)
print(id(a.lst_different_name))
print(id(a.lst_different_name))

print(a.lst_different_name is not a.lst_different_name)

print(id(a.lst_different_name))

Output

[1, 2, 3]
2462895845824
2462895845824
True
2462896109184
KishuInu
  • 61
  • 7
  • I think what is confusing you is the two `print` has the same value for `id()` and only after the `is not` the ID changes? – criztovyl Jul 17 '22 at 19:37
  • I'm getting different results - https://www.toptal.com/developers/hastebin/ciqezibohe.yaml (Python 3.9.2 on Debian). The initial ids printed are different. – SuperStormer Jul 17 '22 at 19:39
  • 4
    You comparing the id of ephemeral objects. Python can reuse the id in these cases. The is documented behavior. – Mark Jul 17 '22 at 19:40
  • @criztovyl Correct! – KishuInu Jul 17 '22 at 19:52
  • @Mark it's not immediately obvious why the objects are ephemeral. It took me at least 3 times of reading the code to see that `copy` in there. – Mark Ransom Jul 17 '22 at 19:52
  • I guess the first sentence about copying primed me to notice. But I agree @MarkRansom, this is easily overlooked on a quick scan of the problem. – Mark Jul 17 '22 at 19:56

0 Answers0