• (python)通过一个代码例子来分析对象的生命周期


    最近在学习python,看的是《简明python教程》,写的很是通俗易懂。

    在一个类和对象的变量的例子中,看到代码运行结果突然想到在python中对象的生命周期的问题,代码运行结果:

    #!/usr/bin/env python
    #
    coding=utf-8
    #
    filename :objvar.py
    class Person:
        population 
    = 0
        
    def __init__(self,name):
            self.name 
    = name
            
    print("initializing %s"%self.name)
            Person.population 
    += 1
        
    def __del__(self):
            
    print("%s say bye"%self.name)
            Person.population 
    -=1
            
    if Person.population == 0 :
                
    print ("I'm the last one")
            
    else:
                
    print ("There are still %d person left"%Person.population)
        
    def SayHi(self):
            
    print ("Hi,my name is %s"%self.name)
        
    def HowMany(self):
            
    if Person.population == 1:
                
    print("I am the only Person here")
            
    else:
                
    print ("We have %d person here"%Person.population)
                
    swaroop 
    = Person("Swaroop"#initializing Swaroop
    swaroop.SayHi()     #Hi,my name is Swaroop
    swaroop.HowMany()   #I am the only Person here

    kalam 
    = Person("Kalam"#initializing Kalam
    kalam.SayHi()   #Hi,my name is Kalam
    kalam.HowMany() #We have 2 person here

    swaroop.SayHi() 
    #Hi,my name is Swaroop
    swaroop.HowMany()   #We have 2 person here

    #Kalam say bye
    #
    There are still 1 person left
    #
    Swaroop say bye
    #
    I'm the last one

    最后四行注释起来的运行结果中,显示kalam对象先被释放,之后才是swaroop被释放。在教程中提到:

    就如同__init__方法一样,还有一个特殊的方法__del__,它在对象消逝的时候被调用。对象消逝即对象不再被使用,它所占用的内存将返回给系统作它用。在这个方法里面,我们只是简单地把Person.population1

    当对象不再被使用时,__del__方法运行,但是很难保证这个方法究竟在 什么时候 运行。如果你想要指明它的运行,你就得使用del语句,就如同我们在以前的例子中使用的那样。

    就是说,代码中后面不再引用对象时,对象自动被系统回收内存。

    可能1、对象的回收(析构)被调用的时间是由对象的引用位置决定的

     

    那按他的意思,结合上面代码段输出的结果来分析因为最后两行代码swaroop,被调用使用了两个方法,所以swaroop对象才在kalam对象释放之后才被回收。

    所以,我把代码修改一下。给Person增加了一个Invoke方法,这个方法什么也不做,只是为了延长对象的生命周期。代码如下:

    #!/usr/bin/env python
    #
    coding=utf-8
    #
    filename :objvar.py
    class Person:
        population 
    = 0
        
    def __init__(self,name):
            self.name 
    = name
            
    print("initializing %s"%self.name)
            Person.population 
    += 1
        
    def __del__(self):
            
    print("%s say bye"%self.name)
            Person.population 
    -=1
            
    if Person.population == 0 :
                
    print ("I'm the last one")
            
    else:
                
    print ("There are still %d person left"%Person.population)
        
    def SayHi(self):
            
    print ("Hi,my name is %s"%self.name)
        
    def HowMany(self):
            
    if Person.population == 1:
                
    print("I am the only Person here")
            
    else:
                
    print ("We have %d person here"%Person.population)
        
    def Invoke(self):
            
    print("ok")
    swaroop 
    = Person("Swaroop"#initializing Swaroop
    swaroop.SayHi()     #Hi,my name is Swaroop
    swaroop.HowMany()   #I am the only Person here

    kalam 
    = Person("Kalam"#initializing Kalam
    kalam.SayHi()   #Hi,my name is Kalam
    kalam.HowMany() #We have 2 person here

    swaroop.SayHi() 
    #Hi,my name is Swaroop
    swaroop.HowMany()   #We have 2 person here

    kalam.Invoke() 
    #ok
    #
    Kalam say bye
    #
    There are still 1 person left
    #
    Swaroop say bye
    #
    I'm the last one

    看完以上的代码,在这儿我就很奇怪了。为了延长对象的生命周期,我专门在代码结尾运行了"kalam.invoke()",就是欲告诉系统在最后我还要使用kalam,请不要回收。但是运行的结果却告诉我回收的动作是在运行"kalam.invoke"之后才开始的,并且回收的顺序还是先回收kalam,后回收Swaroop.

    可能2、对象的释放是由对象被创建的先后顺序来决定的?

    难道是有根据对象创建的先后顺序来决定回收顺序的?就是所谓的:先创建后回收,后创建先回收的原则?不行,我要试一下:

    #!/usr/bin/env python
    #
    coding=utf-8
    #
    filename :objvar.py
    class Person:
        population 
    = 0
        
    def __init__(self,name):
            self.name 
    = name
            
    print("initializing %s"%self.name)
            Person.population 
    += 1
        
    def __del__(self):
            
    print("%s say bye"%self.name)
            Person.population 
    -=1
            
    if Person.population == 0 :
                
    print ("I'm the last one")
            
    else:
                
    print ("There are still %d person left"%Person.population)
        
    def SayHi(self):
            
    print ("Hi,my name is %s"%self.name)
        
    def HowMany(self):
            
    if Person.population == 1:
                
    print("I am the only Person here")
            
    else:
                
    print ("We have %d person here"%Person.population)
        
    def Invoke(self):
            
    print("ok")


    kalam 
    = Person("Kalam"#initializing Kalam
    kalam.SayHi()   #Hi,my name is Kalam
    kalam.HowMany() #I am the only Person here

    swaroop 
    = Person("Swaroop"#initializing Swaroop
    swaroop.SayHi()     #Hi,my name is Swaroop
    swaroop.HowMany()   #We have 2 person here

    swaroop.SayHi() 
    #Hi,my name is Swaroop
    swaroop.HowMany()   #We have 2 person here

    kalam.Invoke() 
    #ok
    #
    Kalam say bye
    #
    There are still 1 person left
    #
    Swaroop say bye
    #
    I'm the last one

    事实上,我再一次被它打败了。很显然,以上代码表明:虽然把swaroop和kalam对象的创建顺序进行了调整,但还是没有改变他们被释放的先后顺序。

    可能3、对象的释放顺序是由对象的引用的变量决定的。

    当我想到这个可能的时候也觉得挺不可思议的,但上面的代码kalam和swaroop怎么调整释放顺序也不改变,我觉得可以放手试一下。

    #!/usr/bin/env python
    #
    coding=utf-8
    #
    filename :objvar.py
    class Person:
        population 
    = 0
        
    def __init__(self,name):
            self.name 
    = name
            
    print("initializing %s"%self.name)
            Person.population 
    += 1
        
    def __del__(self):
            
    print("%s say bye"%self.name)
            Person.population 
    -=1
            
    if Person.population == 0 :
                
    print ("I'm the last one")
            
    else:
                
    print ("There are still %d person left"%Person.population)
        
    def SayHi(self):
            
    print ("Hi,my name is %s"%self.name)
        
    def HowMany(self):
            
    if Person.population == 1:
                
    print("I am the only Person here")
            
    else:
                
    print ("We have %d person here"%Person.population)
        
    def Invoke(self):
            
    print("ok")

    = Person("Swaroop"#initializing Swaroop
    a.SayHi()     #Hi,my name is Swaroop
    a.HowMany()   #I am the only Person here

    = Person("Kalam"#initializing Kalam
    b.SayHi()   #Hi,my name is Kalam
    b.HowMany() #We have 2 person here

    d
    = Person("Smithy")
    d.SayHi()
    d.HowMany()

    = Person("Jackson")
    c.SayHi()
    c.HowMany()

    #Swaroop say bye
    #
    There are still 3 person left
    #
    Jackson say bye
    #
    There are still 2 person left
    #
    Kalam say bye
    #
    There are still 1 person left
    #
    Smithy say bye
    #
    I'm the last one


    看代码运行结果:

    创建对象时顺序为:a-b-d-c(有意为之),而最终对象翻译顺序为:a-c-b-d

    无药可救了。

    我决定去最大的资源库---互联网上查阅一下相关的信息。

  • 相关阅读:
    ABAP Webdynpro Interface View的用法
    ABAP Webdynpro的跟踪工具WD_TRACE_TOOL
    git 速查
    Python 解析含有命名空间(xmlns)的xml文件(基于ElementTree)
    完全显示DataFrame中行、列内容
    解决Jupyter Notebook中for循环输出DataFrame不够美观
    git配置别名
    元素可拖拽(移动端与pc端)
    pointer network和recursive神经网络
    ELMO,BERT和GPT简介
  • 原文地址:https://www.cnblogs.com/sxlfybb/p/1434741.html
Copyright © 2020-2023  润新知