python中的__init__()方法 VS __new__()方法

简介: python中的__init__()方法 VS __new__()方法

1.__init__()方法


__init__()方法是python中一个特殊的方法,它在初始化一个类的实例化对象时候调用__init__()至少有一个参数self,它就是__new__()方法返回的实例对象,__init__()在__new__()的基础上完成一些初始化的操作。__init__()不需要返回值。__init()__方法使用如下例所示:


1# @Author  : Curry_Coder (1217096231@qq.com)
 2# @Link    : https://www.jianshu.com/u/4645adadefec
 3# @Version : $Id$
 4
 5# __init()__
 6
 7class Person:
 8    def __init__(self, name, age):
 9        self.name = name
10        self.age = age
11
12    def __str__(self):
13        return '<Person: {0},{1}>'.format(self.name, self.age)
14
15
16if __name__ == '__main__':
17    p = Person('CurryCoder', 20)
18    print(p)


注意:__init__()方法在实例化类对象的时候,并不是第一个被调用的方法。例如,当使用Person('CurryCoder',20)这样的语句创建Person类的对象p时,最先被调用的方法是__new__()方法。因为只有最先调用__new__()方法才能创建出类的实例p,接着才能调用__init()方法来初始化这个实例对象p。


2.__new__()方法


__new__()方法接收的参数虽然和__init__()方法一样,但__init__()方法是在类实例对象创建之后调用(用它来初始化实例对象),而 __new__()方法则是创建这个类实例对象的方法,优先被调用__new__()方法至少有一个参数cls代表当前类,此参数在实例化时,由Python解释器自动识别。__new__()必须有返回值,返回实例对象。__new()__方法使用如下例所示:


1#!/usr/bin/env python
 2# -*- coding: utf-8 -*-
 3# @Date    : 2020-06-09 09:35:26
 4# @Author  : Curry_Coder (1217096231@qq.com)
 5# @Link    : https://www.jianshu.com/u/4645adadefec
 6# @Version : $Id$
 7
 8# __new()__
 9
10
11class Person:
12    def __new__(cls, *args, **kwargs):
13        print('优先调用__new__()方法创建出实例化对象')
14        _instance = super(Person, cls).__new__(cls, **kwargs)
15        return _instance
16
17    def __init__(self, name, age):
18        print('调用__init__()方法来初始化实例对象')
19        self.name = name
20        self.age = age
21
22    def __str__(self):
23        return '<Person: {0}, {1}>'.format(self.name, self.age)
24
25
26if __name__ == '__main__':
27    p = Person('Person', ('James', 27))
28    print(p)


3.单例模式Singleton


单例模式:一种常见的软件设计模式,该模式的主要目的是确保某一个类只有一个实例对象存在。当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上用场。在Python中,我们可以用多种方法来实现单例模式:  

 a.使用模块  

b.使用__new__()方法  

c.使用装饰器    

d.使用元类metaclass


3.1 使用模块


Python的模块就是天然的单例模式。因为模块在第一次导入时,会生成.pyc文件。当第二次导入时,就会直接加载 .pyc 文件,而不会再次执行模块代码。因此,我们只需把相关的函数和数据定义在一个模块中,就可以获得一个单例对象。如下例所示:


1from mysingleton import my_singleton
2
3my_singleton.foo()



3.2 使用__new__()方法


为了使类只能实例化出一个对象,于是可以使用__new__()方法来控制实例的创建过程。如下例所示:


1#!/usr/bin/env python
 2# -*- coding: utf-8 -*-
 3# @Date    : 2020-06-09 09:35:26
 4# @Author  : Curry_Coder (1217096231@qq.com)
 5# @Link    : https://www.jianshu.com/u/4645adadefec
 6# @Version : $Id$
 7
 8
 9class Singleton(object):
10    _instance = None  # 类变量
11
12    def __new__(cls, *args, **kw):
13        if not cls._instance:
14            cls._instance = super(Singleton, cls).__new__(cls, *args, **kw)  # 将类的实例和一个类变量 _instance 关联起来
16        return cls._instance
17
18
19class MyClass(Singleton):
20    a = 1
21
22
23one = MyClass()
24two = MyClass()
25print(one is two)
26print(id(one), id(two))


3.3 使用装饰器


装饰器(decorator)可以动态地修改一个类或函数的功能。也可以使用装饰器来装饰某个类,使其只能生成一个实例。


1from functools import wraps
 2
 3# 定义了一个装饰器 singleton,它返回了一个内部函数getinstance,该函数会判断某个类是否在字典instances 中,如果不存在,则会将cls作为 key,cls(*args, **kw) 作为 value存到instances中。否则,直接返回instances[cls]
 4
 5
 6def singleton(cls):
 7    instances = {}
 8
 9    @wraps(cls)
10    def getinstance(*args, **kwargs):
11        if cls not in instances:
12            instances[cls] = cls(*args, **kwargs)
13        return instances[cls]
14    return getinstance
15
16
17# 被装饰的函数
18@singleton
19class MyClass(object):
20    a = 1


3.4 使用元类metaclass


元类(metaclass)可以控制类的创建过程,它主要做三件事:a.拦截类的创建b.修改类的定义c.返回修改后的类


1class Singleton(type):
 2    _instances = {}
 3
 4    def __call__(cls, *args, **kwargs):
 5        if cls not in cls._instances:
 6            cls._instances[cls] = super(
 7                Singleton, cls).__call__(*args, **kwargs)
 8        return cls._instances[cls]
 9
10
11class MyClass(metaclass=Singleton):
12    pass


4.参考资料


[1] https://mlln.cn/2018/11/12/python3%E7%9A%84__new__%E5%92%8C__init__%E6%96%B9%E6%B3%95%E7%9A%84%E6%AF%94%E8%BE%83%E5%92%8C%E4%BD%BF%E7%94%A8/#undefined

[2] https://www.cnblogs.com/zhouzhishuai/p/11410986.html

[3] https://www.jianshu.com/p/6f0b6275d27c

相关文章
|
11天前
|
JSON 数据可视化 API
Python 中调用 DeepSeek-R1 API的方法介绍,图文教程
本教程详细介绍了如何使用 Python 调用 DeepSeek 的 R1 大模型 API,适合编程新手。首先登录 DeepSeek 控制台获取 API Key,安装 Python 和 requests 库后,编写基础调用代码并运行。文末包含常见问题解答和更简单的可视化调用方法,建议收藏备用。 原文链接:[如何使用 Python 调用 DeepSeek-R1 API?](https://apifox.com/apiskills/how-to-call-the-deepseek-r1-api-using-python/)
|
26天前
|
数据挖掘 数据处理 开发者
Python3 自定义排序详解:方法与示例
Python的排序功能强大且灵活,主要通过`sorted()`函数和列表的`sort()`方法实现。两者均支持`key`参数自定义排序规则。本文详细介绍了基础排序、按字符串长度或元组元素排序、降序排序、多条件排序及使用`lambda`表达式和`functools.cmp_to_key`进行复杂排序。通过示例展示了如何对简单数据类型、字典、类对象及复杂数据结构(如列车信息)进行排序。掌握这些技巧可以显著提升数据处理能力,为编程提供更强大的支持。
32 10
|
28天前
|
人工智能 自然语言处理 算法
随机的暴力美学蒙特卡洛方法 | python小知识
蒙特卡洛方法是一种基于随机采样的计算算法,广泛应用于物理学、金融、工程等领域。它通过重复随机采样来解决复杂问题,尤其适用于难以用解析方法求解的情况。该方法起源于二战期间的曼哈顿计划,由斯坦尼斯拉夫·乌拉姆等人提出。核心思想是通过大量随机样本来近似真实结果,如估算π值的经典示例。蒙特卡洛树搜索(MCTS)是其高级应用,常用于游戏AI和决策优化。Python中可通过简单代码实现蒙特卡洛方法,展示其在文本生成等领域的潜力。随着计算能力提升,蒙特卡洛方法的应用范围不断扩大,成为处理不确定性和复杂系统的重要工具。
69 21
|
2月前
|
安全
Python-打印99乘法表的两种方法
本文详细介绍了两种实现99乘法表的方法:使用`while`循环和`for`循环。每种方法都包括了步骤解析、代码演示及优缺点分析。文章旨在帮助编程初学者理解和掌握循环结构的应用,内容通俗易懂,适合编程新手阅读。博主表示欢迎读者反馈,共同进步。
|
2月前
|
JSON 安全 API
Python调用API接口的方法
Python调用API接口的方法
410 5
|
23天前
|
存储 缓存 Java
Python高性能编程:五种核心优化技术的原理与Python代码
Python在高性能应用场景中常因执行速度不及C、C++等编译型语言而受质疑,但通过合理利用标准库的优化特性,如`__slots__`机制、列表推导式、`@lru_cache`装饰器和生成器等,可以显著提升代码效率。本文详细介绍了这些实用的性能优化技术,帮助开发者在不牺牲代码质量的前提下提高程序性能。实验数据表明,这些优化方法能在内存使用和计算效率方面带来显著改进,适用于大规模数据处理、递归计算等场景。
58 5
Python高性能编程:五种核心优化技术的原理与Python代码
|
2月前
|
Python
[oeasy]python055_python编程_容易出现的问题_函数名的重新赋值_print_int
本文介绍了Python编程中容易出现的问题,特别是函数名、类名和模块名的重新赋值。通过具体示例展示了将内建函数(如`print`、`int`、`max`)或模块名(如`os`)重新赋值为其他类型后,会导致原有功能失效。例如,将`print`赋值为整数后,无法再用其输出内容;将`int`赋值为整数后,无法再进行类型转换。重新赋值后,这些名称失去了原有的功能,可能导致程序错误。总结指出,已有的函数名、类名和模块名不适合覆盖赋新值,否则会失去原有功能。如果需要使用类似的变量名,建议采用其他命名方式以避免冲突。
52 14
|
2月前
|
分布式计算 大数据 数据处理
技术评测:MaxCompute MaxFrame——阿里云自研分布式计算框架的Python编程接口
随着大数据和人工智能技术的发展,数据处理的需求日益增长。阿里云推出的MaxCompute MaxFrame(简称“MaxFrame”)是一个专为Python开发者设计的分布式计算框架,它不仅支持Python编程接口,还能直接利用MaxCompute的云原生大数据计算资源和服务。本文将通过一系列最佳实践测评,探讨MaxFrame在分布式Pandas处理以及大语言模型数据处理场景中的表现,并分析其在实际工作中的应用潜力。
116 2
|
2月前
|
Unix Linux 程序员
[oeasy]python053_学编程为什么从hello_world_开始
视频介绍了“Hello World”程序的由来及其在编程中的重要性。从贝尔实验室诞生的Unix系统和C语言说起,讲述了“Hello World”作为经典示例的起源和流传过程。文章还探讨了C语言对其他编程语言的影响,以及它在系统编程中的地位。最后总结了“Hello World”、print、小括号和双引号等编程概念的来源。
126 80
|
2月前
|
存储 数据采集 人工智能
Python编程入门:从零基础到实战应用
本文是一篇面向初学者的Python编程教程,旨在帮助读者从零开始学习Python编程语言。文章首先介绍了Python的基本概念和特点,然后通过一个简单的例子展示了如何编写Python代码。接下来,文章详细介绍了Python的数据类型、变量、运算符、控制结构、函数等基本语法知识。最后,文章通过一个实战项目——制作一个简单的计算器程序,帮助读者巩固所学知识并提高编程技能。

热门文章

最新文章

推荐镜像

更多