0

Given the code below

class A:
    def method():
        pass


obj1 = A()
obj2 = A()

print(hex(id(A.method)))
print(hex(id(obj1.method)))
print(hex(id(obj2.method)))

The last two statements print the same address but the first one doesn't.

Why does it need to copy the methods when initializing an object and not use the same address as the class?

fredtux
  • 107
  • 5
  • 1
    Try `print(A.method, obj1.method)` and notice the difference. – Barmar Jul 27 '20 at 22:25
  • So it's because one is a function and the other a bound method? – fredtux Jul 27 '20 at 22:30
  • 1
    Exactly. There are lots of docs online about methods/bound methods, have a bit of a look around – lxop Jul 27 '20 at 22:32
  • Thanks, this helped me a lot – fredtux Jul 27 '20 at 22:32
  • 1
    Strictly speaking, they are not memory address; they are just object identifiers. (CPython uses an address as an implementation detail, but you should not think of it as a memory address.) – chepner Jul 27 '20 at 22:37
  • I'll look into it. I got the idea that they are memory addresses from here https://www.w3schools.com/python/ref_func_id.asp _The id is the object's memory address, and will be different for each time you run the program. (except for some object that has a constant unique id, like integers from -5 to 256)_ – fredtux Jul 27 '20 at 22:39
  • 1
    Yes, but that's just what *CPython* uses for object identifiers. You can't *use* it in any way; for example, you can't get a reference to an object by knowing its identifier. – chepner Jul 27 '20 at 22:57

1 Answers1

1

It's not copying the methods.

When you use instance.method, it creates a new bound method object that binds the method to that instance. This is similar to multiple closures of the same function in different environments.

Note that obj1.method and obj2.method are not actually the same bound method objects. Since you didn't save either object, the first object was discarded immediately and its address was used for the second one. You can prevent this by assigning them to variables.

method1 = obj1.method
method2 = obj2.method
print(hex(id(method1)))
print(hex(id(method2)))

Since the objects can't be garbage collected, they get different IDs.

For other examples of this, see Unnamed Python objects have the same id

Barmar
  • 741,623
  • 53
  • 500
  • 612