首页 > 编程语言 >python中类的__new__方法和__init__方法

python中类的__new__方法和__init__方法

时间:2024-03-17 19:32:15浏览次数:25  
标签:__ python instance init 实例 new cls

python


文章目录


一、python中类的__new__方法和__init__方法

在Python中,__new____init__是类的两个内置方法,它们在创建和初始化类的实例时起着重要的作用。

__new__方法是一个静态方法,当我们创建类的新实例时,它会被首先调用。这个方法的主要任务是创建新的实例并返回它。通常,我们使用super().__new__(cls, *args, **kwargs)来调用父类的__new__方法,这会返回一个新的实例。然后,这个新的实例会被传递给__init__方法作为第一个参数。

__init__方法则是一个实例方法,它在__new__方法创建新实例后被调用,用于初始化新创建的实例。__init__方法接收新创建的实例(通常命名为self)作为第一个参数,然后是我们传递给类构造器的任何参数。

代码例子:

class MyClass:
    def __new__(cls, *args, **kwargs):
        instance = super().__new__(cls)
        # 在这里可以添加一些额外的初始化代码
        return instance

    def __init__(self, arg1, arg2):
        self.arg1 = arg1
        self.arg2 = arg2

总的来说,__new__方法用于创建新的实例,而__init__方法用于初始化这个新创建的实例。

二、第三行解释说明 instance = super().new(cls)

在Python中,如果一个类没有明确指定它的父类,那么它的父类默认是object类。代码中,MyClass没有明确指定父类,所以它的父类是object类。

在Python中,所有的类都直接或间接地继承自object类。object类是最顶层的基类,它提供了一些基本的方法,如__new____init____str____repr__等。

当我们创建一个新的类,而没有明确指定它的父类时,Python会默认让它继承自object类。这意味着我们的类会继承object类的所有方法。

然而,大多数情况下,我们可能不需要直接与object类交互。我们只需要知道,当我们创建一个新的类时,它会自动继承自object类,我们可以覆盖object类的方法来改变它们的行为。

需要注意的是,super().__new__(cls)这行代码是调用父类(在这个例子中是object类)的__new__方法来创建新的实例。这是创建新实例的标准方式,除非我们有特殊的需求,否则通常不需要修改这行代码。

三、init,__new__返回的是什么?

  1. 因为对象是由 __new____init__ 协作构造完成的 (由 __new__ 创建,并由 __init__ 定制),所以 __init__ 返回的值只能是 None,否则会在运行时引发 TypeError

  2. __new__方法返回的是一个新创建的类的实例。在我们的代码中,__new__方法通过调用super().__new__(cls)创建了一个新的MyClass的实例,并将其返回。这个新创建的实例会被传递给__init__方法作为第一个参数,用于初始化实例。

四、debug代码运行中cls,instance,self都是什么东西

在这里插入图片描述

在这里插入图片描述

怎么理解 cls是<class ‘main.MyClass’>,instance是<main.MyClass object at 0x7f4999b6c050>

在Python中,cls是一个常用的约定,用于表示当前类。在类方法(如__new__)中,cls是自动传递的,就像实例方法中的self一样。

在我们的代码中,cls<class '__main__.MyClass'>,这表示cls就是MyClass这个类。

instance<__main__.MyClass object at 0x7f4999b6c050>,这表示instanceMyClass的一个实例,0x7f4999b6c050是这个实例在内存中的地址。

所以,super().__new__(cls)这行代码的作用是创建一个MyClass的新实例,并将这个新实例赋值给instance。然后,__new__方法返回这个新创建的实例。

五、什么时候会重写__new__一般都怎么用,举个例子

在Python中,我们通常不需要重写__new__方法,因为默认的实现已经足够用了。但在某些特殊情况下,我们可能需要重写__new__方法。以下是一些例子:

  1. 实现单例模式:单例模式是一种设计模式,它保证一个类只有一个实例,并提供一个全局访问点。我们可以通过重写__new__方法来实现单例模式。
class Singleton:
    _instance = None

    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super().__new__(cls, *args, **kwargs)
        return cls._instance

在这个例子中,我们在__new__方法中检查是否已经有一个实例存在。如果存在,我们就返回这个实例,否则我们创建一个新的实例。

  1. 控制实例的创建:有时,我们可能想要控制实例的创建。例如,我们可能想要限制只能创建特定数量的实例。我们可以通过重写__new__方法来实现这个功能。
class LimitedInstances:
    _instances = []
    limit = 3

    def __new__(cls, *args, **kwargs):
        if len(cls._instances) >= cls.limit:
            raise RuntimeError("Cannot create more instances")
        instance = super().__new__(cls, *args, **kwargs)
        cls._instances.append(instance)
        return instance

在这个例子中,我们在__new__方法中检查是否已经创建了足够多的实例。如果已经创建了足够多的实例,我们就抛出一个异常,否则我们创建一个新的实例。

演示:

在这里插入图片描述

六、官方链接

https://docs.python.org/zh-cn/3/reference/datamodel.html#object.new

https://docs.python.org/zh-cn/3/reference/datamodel.html#object.init

标签:__,python,instance,init,实例,new,cls
From: https://blog.csdn.net/weixin_73330544/article/details/136782362

相关文章

  • C++ 并发编程指南(11)原子操作
    文章目录一、原子操作1、基本概念2、C++中的原子类型3、示例4、总结前言在C++多线程编程中,原子操作扮演着至关重要的角色。它们提供了一种在多线程环境中安全地访问和修改共享数据的方式,从而避免了数据竞争和不一致性的问题。本文将详细介绍C++中的原子操作,包括其......
  • USB的设备描述符
    1.设备描述符每个USB设备都有有且仅仅有一个设备描述符,它也是主机与设备连接时候读取到的第一个描述符,其总长度为18字节,一共包含了14个字段第一个字段(bLength)代表设备描述符的长度,固定为18字节(0x12),所有标准描述符的第一个字节都代表相应描述符的长度信息。第二个字段(bDes......
  • USB配置描述符
    配置描述符我们的主机枚举过程中,是没有单独获取接口和端点描述符的,这是因为他们都是配置描述符的,当主机获取配置描述符时候,也就意味着会同时获取从属的接口,端点(及其他特定类描述符)。USB主机对于设备描述符的获取是有两次的,第一次只是获取如上图的8个字段,也就是前9个字节,这......
  • USB接口与端点描述符
    主机在第一次发送获取配置描述符的命令时,只会读取配置描述符的前九个字节,它包含了配置描述符以及所有从属的接口,端点(及其他特定类描述符)的总长度。获取其他长度不固定的描述符也是这样分成两步执行如果一个配置描述符不只支持一个接口描述符,并且每个接口描述符都有自己从属......
  • HTML标签
    目录HTMLHTML标签注释标签标题标签段落标签格式化标签图片标签超链接标签css代码表格标签列表标签表单标签单选框复选框按钮选择文件上传下拉菜单多行编辑框div&spanHTMLHTML的全称为超文本标记语言,是一种标记语言。它包括一系列标签,通过这些标签可以......
  • 07.多线程的概述
    1.线程的概述进程--是我们程序的执行实例,进程在执行的时候,真正执行的就是进程中的线程,进程只是提供了线程执行的资源(PCB)。---进程包含线程进程:进程指正在运行的程序。确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于运行过程中的程序,并且具有一定独立功能。线程:......
  • 第三章作业
    一、分析题实现如下图的页面布局indexwxml//index.wxml<viewclass="content"><viewclass="layout-top"><viewclass="screen">168</view></view><viewclass="layout-bottom"><viewcla......
  • pycharm汉化
    汉化之后的样子打开pycharm软件,点击以下图标(由于本人已经汉化完成,所以可以再打开软件之后直接按键盘上面的ctrl+Alt+s,效果是一样的)打开之后会出现这个界面点击安装即可(我已经安装过了,所以显示的更新)做完之后即可汉化成功......
  • 时间序列(二)——实践中应用
    时间序列(二)实践中选择模型通过p、d、q决定需要的模型超参数p的确定超参数q的确定一般情况下如何确定p和q实践中选择模型通过p、d、q决定需要的模型ARIMA模型的公式可以表示为:Y......
  • 数据结构之顺序表(C语言版)
    顺序表是数据结构中最基本的一种线性表,它以一段连续的存储空间来存储数据元素,元素之间的顺序由它们在内存中的位置来决定。在C语言中,我们通常使用数组来实现顺序表。目录顺序表的结构定义顺序表的基本操作应用实例顺序表的结构定义首先,我们需要定义一个结构体来表......