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.使用元类metaclass3.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
[3] https://www.jianshu.com/p/6f0b6275d27c