【问题标题】:Python __init__ Compared to C++ ConstructorPython __init__ 与 C++ 构造函数的比较
【发布时间】:2017-10-21 14:34:16
【问题描述】:

我已经使用 Python 大约 4 年了,最近开始学习 C++。在 C++ 中,您为每个类创建了一个构造方法我想知道认为这与 Python 中的 __init__(self) 函数等效是否正确?有什么显着的区别吗? C++ 析构函数与 Python _exit__(self)

的相同问题

【问题讨论】:

  • 你做过研究吗?
  • init 函数是调用类时首先执行的。但是,C++ 中的构造函数可以单独调用。除了属于一个类之外,构造函数和python中的init函数几乎没有任何相似之处。
  • 我建议您获取a good beginners book or two 阅读。它应该为您提供有关构造函数和析构函数的所有信息。
  • 在 Python 中,对象构造函数是 __new__,但您不经常看到它,因为很少需要覆盖从 object 继承的 __new__。严格来说,__init__ 初始化由__new__ 创建的新实例,但在随意讨论中调用__init__ 构造函数是相当常见的。
  • 他在问__init__ 和构造函数是否相同;他们不是。

标签: python c++ constructor


【解决方案1】:

是的,Python 的 __init__ 类似于 C++ 的构造函数。两者通常都是初始化非静态数据成员的地方。在这两种语言中,这些函数都将 in-creation 对象作为第一个参数,在 Python 中显式并按照约定命名为 self,在 C++ 中隐式并按照语言命名为 this。在这两种语言中,这些函数都不会返回任何内容。两种语言之间的一个显着区别是,在 Python 基类中 __init__ 必须从继承的类 __init__ 中显式调用,而在 C++ 中它是隐式和自动的。 C++ 还可以通过成员初始化器列表和非静态数据成员初始化器在构造函数主体之外声明数据成员初始化器。在某些情况下,C++ 还会为您生成默认构造函数。

Python 的 __new__ 类似于 C++ 的类级别 operator new。两者都是静态类函数,必须返回一个值才能继续创建。在 C++ 中,它是指向内存的指针,而在 Python 中,它是正在创建的类类型的 未初始化 值。

Python 的 __del__ 在 C++ 中没有直接的类似物。它是一个对象终结器,它也存在于其他垃圾收集语言(如 Java)中。它不会在词法上预先确定的时间调用,但运行时会在需要释放对象时调用它。

__exit__ 的作用类似于 C++ 的析构函数,因为它可以提供确定性清理和词法预定点。在 C++ 中,这往往是通过 RAII 类型的 C++ 析构函数来完成的。在 Python 中,同一个对象可以多次调用 __enter____exit__。在 C++ 中,这将通过单独的 RAII 资源持有类型的构造函数和析构函数来完成。例如,在 Python 中,给定一个互斥锁类型的实例lock,可以说with lock: 来引入一个临界区。在 C++ 中,我们创建一个不同类型的实例,将锁作为参数std::lock_guard g{lock} 来完成同样的事情。 Python __enter____exit__ 调用映射到 C++ RAII 类型的构造函数和析构函数。

【讨论】:

  • __del__ 不像 C++ 中的 delete 吗?
  • 可以说 C++ 析构函数最重要的特性是它们在预定时间运行,即退出范围。该行为的类似物是__exit__,因为不能保证在任何特定时间调用__del____del__ 是一个终结器,在回收存储之前调用。在 C++ 中,析构函数与释放是分开的,尽管这两种操作经常一起发生。特别是,在释放之前,不会再存在任何对象,即使我们愿意,也不会自动调用任何对象。
  • 我不是在谈论析构函数,我是说在__del__和delete之后内存都被回收了,所以我认为我们可以将__del__视为类似于delete。
  • 好的,这很公平。我可以同意这一点。我要做出的一个区别是,大多数这些东西通常由语言隐式调用(del 在生命周期结束时,enterexit)并且 delete 是由用户显式调用的。
【解决方案2】:

最好的说法是__init__ 和 C++ 构造函数在新对象生命周期的大致相同时间点被调用,__del__ 和 C++ 析构函数也在生命周期快结束时被调用的一个对象。然而,语义明显不同,每种语言的执行模型使得进一步比较更加困难。

只要说__init__ 用于初始化一个对象创建之后就足够了。 __del__ 就像一个析构函数,可能在对对象的最后一个引用消失后的某个未指定的时间点被调用,__exit__ 更像是一个回调在 with 语句的末尾调用,无论对象的引用计数是否达到零。

【讨论】:

    【解决方案3】:

    我想知道是否认为这等同于 Python 中的init(self) 函数?

    没有。只要看一下语句的结构就可以理解。实际上,self 是对实例的引用。因此,必须在调用__init__ 之前构造实例。

    请参阅this 了解更多信息(__new__ 实际上是您要查找的内容)

    C++ 析构方法与 Python _exit__(self)

    没有。 __exit__ 只退出与对象相关的运行时上下文。在这种情况下,您真正​​要查找的是__del__

    参见this,其中明确说明:

    在实例即将被销毁时调用。这也被称为 一个析构函数。

    【讨论】:

    • __del__ 也不能保证被调用;仅当正在运行的解释器需要对实例进行垃圾收集时才调用它。如果由于解释器退出而导致引用计数变为零,则它不会打扰调用__del__
    • 是的,你完全正确,但这仍然是 Python 中的等价物。我错了吗?
    • 这是 Python 提供的最接近的东西,但并不等同。通常放在构造函数中的代码改为放在上下文管理器的__exit__ 方法中。但是,__exit__ 被调用的事实并不意味着该对象正在消失。您可以轻松定义一个对象,该对象可与多个连续的with 语句一起使用,并在适当时调用其__enter____exit__ 方法。
    • 正如我在回答中所说,__exit__ 不是解构函数。但是,另一方面,__del__ 可以称为一个。无论如何,按照我的链接,文档说它。
    • __init__ 更像是 C++ 中的构造函数。和 self 一样,c++ 中的构造函数也隐式传递了“this”指针作为第一个参数。一些基本的初始化也可能发生在“this”指向的传递内存中。
    猜你喜欢
    • 2016-09-29
    • 2012-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-15
    • 1970-01-01
    相关资源
    最近更新 更多