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