【问题标题】:How do constructors and destructors work?构造函数和析构函数是如何工作的?
【发布时间】:2011-01-26 20:22:51
【问题描述】:

我正在尝试理解这段代码:

class Person:
    '''Represents a person '''
    population = 0

    def __init__(self,name):
          //some statements and population += 1
    def __del__(self):
          //some statements and population -= 1 
    def sayHi(self):
        '''grettings from person'''
        print 'Hi My name is %s' % self.name

    def howMany(self):
        '''Prints the current population'''
        if Person.population == 1:
            print 'i am the only one here'
        else:
            print 'There are still %d guyz left ' % Person.population
rohan = Person('Rohan')
rohan.sayHi()
rohan.howMany()


sanju = Person('Sanjivi')
sanju.howMany()

del rohan # am i doing this correctly? 

析构函数是如何被调用的——自动调用还是我必须像上面那样在“主”程序/类中添加一些东西?

输出:

初始化人员数据
******************************************
初始化 Rohan
******************************************
现在的人口是:1
嗨,我叫罗汉
我是这里唯一的一个
初始化人员数据
******************************************
初始化 Sanjivi
******************************************
现在的人口是:2
如果人死了:
******************************************
三吉维再见世界
还有1人
我是这里唯一的一个
如果人死了:
******************************************
洛汗再见世界
我是地球上最后一个人
现在的人口是:0

如果需要,我也可以粘贴整个课程。我正在学习: http://www.ibiblio.org/swaroopch/byteofpython/read/

【问题讨论】:

  • 请学会使用代码示例所需的缩进。
  • 您的问题是什么?如果您可以总结您的问题,这将有助于我们回答。如果那本书没有帮助,那么还有几十本书可能更有帮助。
  • 如果我错了,请纠正我,但我认为他希望有人用简单的英语向他解释构造函数和解构函数。只是预感。
  • 就像 dclowd9901 说我希望有人用英语解释构造函数和解构函数——如果我不清楚,我很抱歉——我对编程很陌生——感谢任何帮助。
  • "explain" 含糊不清——它可能意味着任何东西。它可能意味着“解释它是如何由编译器实现的”或“解释它如何映射到关系数据库”或“解释为什么这段代码不起作用”或“解释为什么我什至关心 OO 设计”。很抱歉我太啰嗦了,但“解释”似乎是开放式的,很难回答。

标签: python class destructor


【解决方案1】:

这是一个有点自以为是的答案。

不要使用__del__。这不是 C++ 或为析构函数构建的语言。 __del__ 方法确实应该在 Python 3.x 中消失,尽管我相信有人会找到一个有意义的用例。如果您需要使用__del __,请注意http://docs.python.org/reference/datamodel.html 的基本限制:

  • __del__ 在垃圾收集器碰巧收集对象时调用,而不是在您丢失对对象的最后一个引用时调用,而不是在执行 del object 时调用。
  • __del__ 负责调用超类中的任何 __del__,尽管它不是 明确这是按方法解析顺序 (MRO) 还是仅调用每个超类。
  • 拥有__del__ 意味着垃圾收集器放弃检测和清理任何循环链接,例如丢失对链接列表的最后引用。您可以从gc.garbage 获取忽略的对象列表。您有时可以使用弱引用来完全避免循环。时不时会对此进行辩论:请参阅http://mail.python.org/pipermail/python-ideas/2009-October/006194.html
  • __del__ 函数可以作弊,保存对对象的引用并停止垃圾回收。
  • __del__ 中显式引发的异常将被忽略。
  • __del____new__ 的补充远远超过 __init__。这变得令人困惑。请参阅 http://www.algorithm.co.il/blogs/index.php/programming/python/python-gotchas-1-del-is-not-the-opposite-of-init/ 了解解释和问题。
  • __del__ 不是 Python 中“深受喜爱”的孩子。您会注意到 sys.exit() 文档没有指定是否在退出之前收集垃圾,并且存在许多奇怪的问题。在全局变量上调用 __del__ 会导致奇怪的排序问题,例如 http://bugs.python.org/issue5099。即使__init__ 失败,是否应该调用__del__?有关长线程,请参阅http://mail.python.org/pipermail/python-dev/2000-March/thread.html#2423

但是,另一方面:

还有我不喜欢__del__ 功能的个人原因。

  • 每当有人提出 __del__ 时,都会演变成 30 条令人困惑的消息。
  • 它打破了 Python 之禅中的这些项目:
    • 复杂胜于复杂。
    • 特殊情况不足以打破规则。
    • 错误绝不应该悄无声息地过去。
    • 面对模棱两可,拒绝猜测的诱惑。
    • 应该有一种——最好只有一种——明显的方法。
    • 如果实现难以解释,那就是个坏主意。

所以,找个理由不使用__del__

【讨论】:

  • 真棒查尔斯 - 虽然它更具技术性,但我现在更好地理解它 - 最后一个问题 - 当我创建一个对象时 - 它真的会被破坏/释放吗?就像你说的不使用 del 那样做一些小功能并让它在输出中按我想要的方式工作会更好吗?再次提前感谢
  • 经过深思熟虑,我不得不说我不知道​​。如果对象没有在顶层声明,那么它将被收集。顶级对象不太清楚。对不起。
  • 谢谢查尔斯 - 你帮了大忙
  • 请注意,目前由于python3.4+引入PEP 442,GC能够在大部分上调用__del__循环。您应该更新关于这一点的答案。
  • 抱歉,“GC 猜测何时在 Python 3.4+ 版本上调用 del”是否正确?
【解决方案2】:

根据我早期的 CPTS 经验,我对它们的理解:

构造函数:构造函数主要用于类中,用值初始化类,并提供机会在创建的基础上做一些后台工作。如果您在创建对象期间传入值,则可以在此处处理将这些值分配给类中的变量的位置。 (在这种情况下,在构造时,您将增加一个跟踪人口的变量)。

析构函数:析构函数清理一个类。在 python 中,由于垃圾收集器,它不如可以留下悬挂指针的语言 (c++) 重要。 (在这种情况下,您在销毁对象时递减人口变量)。

【讨论】:

  • 感谢 Hortinstein 的简单明了的解释——所以我写的东西有意义吗??我是否使用了“del rohan” - 删除对象以便调用析构函数??
  • 不,del rohan不会调用析构函数。它将减少rohan 对象的引用计数并从该范围中删除名称。 如果引用计数达到0 那么析构函数将被调用。这是一个微妙但重要的区别。
  • hmm 所以如果我不使用 del rohan -- 我的析构函数 def __del__(self) 根本不会被执行??问这个是因为早些时候我根本没有使用 del ,所以 def __del__(self) 没有任何效果——如果我错了,请纠正我——因为我没有清楚地了解这个析构函数是否会涉及自身如果不;不使用del
猜你喜欢
  • 1970-01-01
  • 2013-07-07
  • 2018-09-23
  • 2021-07-28
  • 2011-04-03
  • 2010-12-16
  • 2016-11-04
  • 2011-04-06
  • 2011-12-27
相关资源
最近更新 更多