python单实例
什么是python的单实例?
在python中如果没有特意指定我们所创建类的基类时,那么所有的类都继承于type这个类的祖宗,所有我们创建的类都是type这个鼻祖的实例。
例如:
class A: def __init__(self): self.welcom = "hello world!" def __str__(self): return repr(self.welcom) a = A() print(a) 这是一个简单的类,在定义的时候没有显示的指定A这个类的基类,所以A这个类默认继承自type这个类。那么类A就是type的实例, a = A() #a 是A的实例。
那么当我们这么做的时候
b = A()
c = A()
.....时,我们就创建了多个类A的实例出来,那么他们(a,b,c)这些类的实例都是独立的,因为我们没做一次类似d =A()这样的行为时,都会在内存中将上面所编写的这段代码复制一次存放在不同的内存空间,这就表明了它们这些类A的实例之间是没有关联的,谁也影响不到谁,
我们可以验证一下通过以下代码的输出
class A: def __init__(self): self.welcom = "hello world!" def __str__(self): return repr(self.welcom) a = A() b = A() c = A() print(id(a)) print(id(b)) print(id(c)) id(a)是用来输出a这个实例所在的内存空间地址的,可以看到它们所在的内存空间地址是不同的。
那么单实例的概念到此为止就很明显了,就是每当我做一次类似于这样(a=A())的操作的时候,不让我编写的那段代码复制到内存中另一个地址空间去,而是让他们的引用同一段代码,就相当于我定义一个函数
def single():
print("you can reference me !") a = single b = single c = single print(id(a)) print(id(b)) print(id(c)) 当我打印它们在
内存中的地址空间的时候,输出的结果是这样的,它们实例化这个函数的时候并没有复制代码到另外的内存空间中去。
那么在定义类的时候怎么做到这样的单实例化一个类呢
def singleton(cls): instace = {} def getinstance(): if cls not in instace: instace[cls] = cls() return instace[cls] return getinstance class Count: def __init__(self): self.age = 1 self.name = 'zhuwei' def __str__(self): return ("name is: %s age is %s " % (self.name,self.age)) Single = singleton(Count) a = Single() print(a) b = Single() print(b) print(a is b) print(id(a)) print(id(b)) print(id(b)) 利用闭包(闭包就是在一个函数中嵌套一个或者多个函数,并且这个嵌套的函数可以访问它上级函数的变量,外层函数接受类或者函数作为参数,并且在最后返回嵌套中的函数)的方法实现类的单实例,
def singleton(cls): instace = {} def getinstance(): if cls not in instace: instace[cls] = cls() return instace[cls] return getinstance class Count: def __init__(self): self.age = 1 self.name = 'zhuwei' def __str__(self): return ("name is: %s age is %s " % (self.name,self.age)) Single = singleton(Count) a = Single() print(a) b = Single() print(b) print(a is b) print(id(a)) print(id(b)) print(id(b))
这两个类的实例在内存空间中的地址是一样的
利用闭包(闭包就是在一个函数中嵌套一个或者多个函数,并且这个嵌套的函数可以访问它上级函数的变量,外层函数接受类或者函数作为参数,并且在最后返回嵌套中的函数)的方法实现类的单实例,
还可以利用python中__new__这个魔术方法来实现类的单实例
class SingleTON: instace = None #def __new__(cls,name,base,dic): def __new__(cls,*args,**kwargs): if cls.instace is None: cls.instace = super(SingleTON,cls).__new__(cls,*args,**kwargs) return cls.instace def __init__(self): self.name = 'zhuwei' a = SingleTON() b = SingleTON() print(id(a)) print(id(b))