用 Python 创建实例

引言

在本文中,我们将深入探讨在 Python 中实例化一个新对象时究竟发生了什么。掌握了这些知识,我们就可以很好地控制实例的创建,这使我们能够以强大的方式定制 Python 对象。那么让我们开始吧。

那么,当我们在 Python 中创建一个新对象时,幕后会发生什么呢?

让我们使用一个模拟 Employee 实体的基本类示例来理解这一点。

class Employee:def __init__(self, name, age):print(type(self), self.__dict__)    # debug stat.self.name = nameprint(self.__dict__)                # debug stat.self.age = ageprint(self.__dict__)                # debug stat.

上面定义的 Employee 类构造函数接受 name 和 age 属性。我们添加了一些调试输出,以便在执行赋值语句时监视实例字典的状态。让我们创建一个 Employee 类的对象并观察结果: 

>>> p = Employee('Sarah', 27)
 {}
{'name': 'Sarah'}
{'name': 'Sarah', 'age': 27}

如果我们仔细观察,我们会看到 self 已经具有所需的类型,即。实例字典最初是空的,但随着我们继续前进,字典由对 self 属性的赋值填充。

需要注意的一点是__init__ 方法不返回任何内容。它只是简单地改变给定的实例。

因此,我们可以确定地说,__init__ 负责初始化它已经给出的实例。

现在显而易见的问题是,如果不是 __init__,那么谁负责创建实例?

如果我们使用内置的 dir 方法查看 Employee 类的特殊方法,我们可以看到一个名为__new__的方法。

>>> dir(p)
['__class__', '__ne__', '__new__', ... , 'age', 'name']

我们没有在 Employee 类中定义 __new__,但是我们确实从通用基类对象继承了一个实现。因此,在这种情况下,正是 __new__ 的基类实现负责分配对象。

>>> p.__new__

>>> p.__new__ is object.__new__
True

上面的代码片段证实了 __new__ 实际上与对象 new 是同一个方法。

因此,__new__() 将传递给 _init_() 构造函数的对象分配为 self。

现在,让我们尝试重写 __new__ 方法,以更好地理解它的签名。我们将实现 __new__ 最基本的覆盖,它只是委托给基类实现,同时添加一些 print 语句,以检查参数和返回值。

class Employee:def __new__(cls, *args, **kwargs):print("args=", repr(args))print("kwargs=", repr(kwargs))obj = super().__new__(cls)     # same as object.__new__(cls)print("id(obj)=", id(obj))return objdef __init__(self, name, age):print("id(self)=", id(self))self.name = nameself.age = age

首先要注意的是,__new__ 是一个类方法。它期望 cls 作为它的第一个参数而不是 self。cls 参数是将被分配的新对象的类。此外,__new__ 接受传递给构造函数的任何参数。在这种情况下,我们使用了 *args 和 **kwargs。

__new__ 的主要目的是分配调用类的实例。所有对象分配必须由最终基类对象上的 __new__ 实现完成。我们使用 super() 来引用对象 new 方法,因为它更易于维护。

最后,我们返回新创建的对象 obj,该对象作为 self 传递给 __init__ 方法。这可以通过比较两个对象的 id 来确认。

>>> p = Employee('Sarah', 27)
args= ('Sarah', 27)
kwargs= {}
id(obj)= 4473868880
id(self)= 4473868880

从上面的代码中,我们可以看到 __new__ 中 obj 的 id 等于 __init__ 中 self 的 id,而且参数已经按照预期转发给了 __new__。

因此,对象分配的总体机制可以总结为下图。

总结

我们已经讨论了实例分配和初始化之间的区别,希望对你加强对 python 创建实例有帮助~

·  END  ·

HAPPY LIFE


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部