1

I was ashamed of a question that occupied my mind, if it is possible and you have the opportunity, thank you for answering: that when we create a instance of a class, the methods of that instance object, especially that instance, are created with the instance (object) or i mean that to run a method, the address of that method in the class with object parameters is referred to as the method class, and if this is not done, it does not cause memory consuming? I did a lot of research on this subject, but I was not arrested much, and I wrote and executed this code:

class a:
    def func1(self,name):
        print("hello")
        
b=a()
c=a()
print(id(a.func1))
print(id(b.func1))
print(id(c.func1))

The address I got from the last two lines is exactly the same. The output was something like this: 76767678900 87665677888 87665677888

And why 2 last address is alike? Thanks a lot

8
  • But I think, it should not be. Ideally all ids should be equal. Can you rerun and see? Commented Jul 1, 2021 at 2:18
  • 2
    @hygull: Nope. a.func1 is the original function (which will be stable within a given run if you don't redefine a or a.func1), the others are bound methods created on demand and thrown away after each use (which might have the same ID if they happen to reuse the same memory, or might not). Commented Jul 1, 2021 at 2:24
  • Hmm, got it. I think I need to get into more details, thanks @ShadowRanger. As I ran and found same ids so. Commented Jul 1, 2021 at 2:31
  • @hygull: It should be definitionally impossible for a.func1 (where a is the class itself) to match b.func1 or c.func1 (which are bound methods), given that a.func1 is never cleaned up, so it continues to possess the same id the whole time (rendering that id unavailable to b.func1 and c.func1). Are you sure you aren't missing a subtle change in the middle of the addresses, or accidentally printing all bound methods or all (unbound) functions? Commented Jul 1, 2021 at 2:36
  • 1
    Let us continue this discussion in chat. Commented Jul 1, 2021 at 2:45

1 Answer 1

1

The first address corresponds to the original function (you accessed it on the class, so it didn't bind it, you just saw the address where the raw function itself was allocated).

The other two (identical) addresses are bound method objects. You immediately released the bound method it allocated, and CPython makes use of both per-type freelists (not sure if any involved here) and a small object allocator that will frequently return the same memory just freed if you ask for the same amount of memory immediately thereafter. If you extracted the underlying function from the bound method, e.g.:

print(id(b.func1.__func__))

you'd see it is the same as a.func1 (and that value will be stable, where the address of the bound methods could differ every time you bind them).

In short, ids are only unique within the current set of objects in the program; if you release one of those objects, its id could appear attached to some other newly allocated object immediately thereafter.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.