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

相关文章
|
1月前
|
测试技术 API Python
【10月更文挑战第1天】python知识点100篇系列(13)-几种方法让你的电脑一直在工作
【10月更文挑战第1天】 本文介绍了如何通过Python自动操作鼠标或键盘使电脑保持活跃状态,避免自动息屏。提供了三种方法:1) 使用PyAutoGUI,通过安装pip工具并执行`pip install pyautogui`安装,利用`moveRel()`方法定时移动鼠标;2) 使用Pymouse,通过`pip install pyuserinput`安装,采用`move()`方法移动鼠标绝对位置;3) 使用PyKeyboard,同样需安装pyuserinput,模拟键盘操作。文中推荐使用PyAutoGUI,因其功能丰富且文档详尽。
WK
|
27天前
|
Python
Python中format_map()方法
在Python中,`format_map()`方法用于使用字典格式化字符串。它接受一个字典作为参数,用字典中的键值对替换字符串中的占位符。此方法适用于从字典动态获取值的场景,尤其在处理大量替换值时更为清晰和方便。
WK
70 36
|
1月前
|
机器学习/深度学习 数据采集 数据挖掘
11种经典时间序列预测方法:理论、Python实现与应用
本文将总结11种经典的时间序列预测方法,并提供它们在Python中的实现示例。
67 2
11种经典时间序列预测方法:理论、Python实现与应用
|
19天前
|
开发者 Python
Python中__init__.py文件的作用
`__init__.py`文件在Python包管理中扮演着重要角色,通过标识目录为包、初始化包、控制导入行为、支持递归包结构以及定义包的命名空间,`__init__.py`文件为组织和管理Python代码提供了强大支持。理解并正确使用 `__init__.py`文件,可以帮助开发者更好地组织代码,提高代码的可维护性和可读性。
18 2
|
27天前
|
安全 数据库 C++
Python Web框架比较:Django vs Flask vs Pyramid
Python Web框架比较:Django vs Flask vs Pyramid
37 1
|
1月前
|
开发者 Python
Python中的魔法方法与运算符重载
在Python的奇妙世界里,魔法方法(Magic Methods)和运算符重载(Operator Overloading)是两个强大的特性,它们允许开发者以更自然、更直观的方式操作对象。本文将深入探讨这些概念,并通过实例展示如何利用它们来增强代码的可读性和表达力。
|
1月前
|
安全 数据库 C++
Python Web框架比较:Django vs Flask vs Pyramid
Python Web框架比较:Django vs Flask vs Pyramid
30 4
|
1月前
|
安全 数据库 C++
Python Web框架比较:Django vs Flask vs Pyramid
【10月更文挑战第10天】本文比较了Python中三个最受欢迎的Web框架:Django、Flask和Pyramid。Django以功能全面、文档完善著称,适合快速开发;Flask轻量灵活,易于上手;Pyramid介于两者之间,兼顾灵活性和安全性。选择框架时需考虑项目需求和个人偏好。
36 1
|
5天前
|
存储 数据挖掘 开发者
Python编程入门:从零到英雄
在这篇文章中,我们将一起踏上Python编程的奇幻之旅。无论你是编程新手,还是希望拓展技能的开发者,本教程都将为你提供一条清晰的道路,引导你从基础语法走向实际应用。通过精心设计的代码示例和练习,你将学会如何用Python解决实际问题,并准备好迎接更复杂的编程挑战。让我们一起探索这个强大的语言,开启你的编程生涯吧!
下一篇
无影云桌面