1. 概述
Python类中,有大量的特殊方法,方法名是“_ _ xxx _ _”,在进行特定的操作时会自动被调用,这些方法称为魔术方法。
以下常见的魔术方法:
_ _ init _ _ 方法:初始化一个类,在创建实例对象为其赋值时调用。
_ _ str _ _ 方法:将对象转换成字符串。
_ _ new _ _ 方法:创建并返回一个实例对象,一般用于单例模式。
_ _ class _ _ 方法:获得已知对象的类。
_ _ del _ _ 方法:对象在程序运行结束后进行对象的销毁的时候调用这个方法,来释放资源。
2. __ new __ 和 __ init __ 的区别
_ _ init _ _ 是初始化方法,创建对象后立刻被默认调用,可接收参数;
_ _ new _ _ 必需至少有一个名为 cls(class)的参数,代表当前类,此参数在实例化时由python解析器自动识别;
_ _ new _ _ 必需有返回值,返回实例化出来的实例,可以return父类:return object._ _ new _ (cls) 或 return super(). _ new _ _(cls) ;
_ _ init _ _ 有一个名为self的参数,它是 _ _ new _ _ 返回的实例,_ _ init _ _ 在 _ _ new _ _ 的基础上完成一些其它初始化的动作, _ _ init _ _不需要返回值;
如果 _ _ new _ _ 创建的时当前实例,那么它会自动调用 _ _ init _ _ 函数,如果时其他类的类名,那么它创建返回的就是其他类的实例,不会调用当前类的_ _ init _ _ 函数,也不会调用其他类的 _ _ init _ _ 函数。
3. 单例模式
3.1 概述
单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在。
应用场景如:系统的回收站、资源管理器......
3.2 Python实现单例模式
3.2.1 基于_ _ new _ _ 方法(推荐使用)
import threading
import time
class Singleton(object):
"""支持多线程版的单例模式"""
instance = None # 静态变量、类变量
lock = threading.RLock()
def __init__(self, name):
"""初始化对象"""
self.name = name
def __new__(cls, *args, **kwargs):
"""创建对象"""
if cls.instance:
return cls.instance
with cls.lock:
if not cls.instance:
time.sleep(0.2)
cls.instance = object.__new__(cls)
return cls.instance
# obj1 = Singleton("gqf")
# obj2 = Singleton("gqf")
# print(obj1)
# print(obj2)
def fun():
obj = Singleton('gqf')
print(obj)
for i in range(10):
task = threading.Thread(target=fun)
task.start()
3.2.2 使用模块(import)
# mysingleton.py
"""
Python 的模块就是天然的单例模式,因为模块在第一次导入时,会生成 .pyc 文件,当第二次导入时,就会直接加载 .pyc 文件,而不会再次执行模块代码。因此,我们只需把相关的函数和数据定义在一个模块中,就可以获得一个单例对象了。
"""
class Singleton(object):
def foo(self):
pass
singleton = Singleton()
# test.py
from mysingleton import singleton
print(singleton)
3.2.3 使用装饰器
def Singleton(cls):
_instance = {}
def _singleton(*args, **kwargs):
if cls not in _instance:
_instance[cls] = cls(*args, **kargs)
return _instance[cls]
return _singleton
@Singleton
class A(object):
a = 1
def __init__(self, x=0):
self.x = x
a1 = A(2)
a2 = A(3)
3.2.4 使用类
class Singleton(object):
def __init__(self):
pass
@classmethod
def instance(cls, *args, **kwargs):
if not hasattr(Singleton, "_instance"):
Singleton._instance = Singleton(*args, **kwargs)
return Singleton._instance
3.2.5 基于元类方式
import threading
class SingletonType(type):
_instance_lock = threading.Lock()
def __call__(cls, *args, **kwargs):
if not hasattr(cls, "_instance"):
with SingletonType._instance_lock:
if not hasattr(cls, "_instance"):
cls._instance = super(SingletonType,cls).__call__(*args, **kwargs)
return cls._instance
class Foo(metaclass=SingletonType):
def __init__(self,name):
self.name = name
obj1 = Foo('name')
obj2 = Foo('name')
print(obj1,obj2)