Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
388 views
in Technique[技术] by (71.8m points)

python - Different class instances use same memory location

I was playing around with the pickle library, when I noticed that sometimes, different class instances are at the same memory location.

Both of the below examples are showcasing said behaviour:

class DemoClass:
    def __init__(self):
        self.name = 'demoName'

#example 1
for i in range(3):
    print (DemoClass())

#example 2
[print(DemoClass()) for i in range(3)]

#Output for both example 1 and example 2
#Note that the memory locations are identical in the output
<__main__.DemoClass object at 0x00CEE610>
<__main__.DemoClass object at 0x00CEE610>
<__main__.DemoClass object at 0x00CEE610>

This was quite startling to me, so maybe you could explain why this occurs.

The way in which the program acts as I would expect it to is as follows.

demo = [DemoClass() for i in range(3)]
for i in demo:
    print (i)

#Output
<__main__.DemoClass object at 0x01F7E630>
<__main__.DemoClass object at 0x01F7ED30>
<__main__.DemoClass object at 0x01F7E670>
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Your question concerns how Python allocates memory. tldr; Python uses a heap to store memory. When a resource is freed, it goes to the top of the heap.

Detailed Answer

Python has to allocate memory to create an instance of an object. For memory efficiency, the Python memory manager has a heap of memory locations available to give or reserve for the instantiation of objects. Using some of your examples, you can see how this works in practice.

Example #1

>>> for i in range(3):
...     print(DemoClass())
... 
<test.DemoClass instance at 0x288b248>
<test.DemoClass instance at 0x288b248>
<test.DemoClass instance at 0x288b248>

During the first iteration of the for loop, python uses the first available address in its current heap, namely <0x288b248>, to create an instance of DemoClass for the print call. Once the print command has finished, the memory address is freed and returns to the top of the heap. During the next iteration of the loop, python utilizes the first available memory address, which again is address <0x288b248>. Etc.

Example #2

>>> for j in [DemoClass() for i in range(3)]:
...     print(j)
... 
<test.DemoClass instance at 0x288bcf8>
<test.DemoClass instance at 0x288b290>
<test.DemoClass instance at 0x288b638>

Here python generates a list that it will then iterate through. The creation of the list requires that a new instance of DemoClass be created for each element. This will take the top three addresses off the heap. After the loop is done, the list is freed from memory and if we again make a call to print(DemoClass) we will find that the python is again reusing memory.

>>> print DemoClass()
<test.DemoClass instance at 0x288bcf8>

Example 3 (My Example of Alternating Memory Allocation)

>>> for i in range(4):
...     Demo = DemoClass()
...     print(Demo)
... 
<test.DemoClass instance at 0x288bcf8>
<test.DemoClass instance at 0x288b290>
<test.DemoClass instance at 0x288bcf8>
<test.DemoClass instance at 0x288b290>

In this example, each time Demo is instantiated as an instance of DemoClass, a segment of memory is assigned to Demo. However, the call to print(Demo) does not free the memory assigned to Demo. At the beginning of the next loop, a new segment of memory is allocated to Demo and then Demo is overwritten, at which point it's original memory address returns to the top of the heap. The memory address used for Demo then alternates between two memory addresses.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...