意图:
想要改变实例创建的方式,以此来实现单例模式,缓存,或者其他类似的特征。
解决方法:
大家要知道的时,python创建实例的过程更像是调用函数。
如果想定制化这个过程,则需要借助元类的定义并且重新实现它的__call__()方法。如下有个例子:
class NoInstance(type):
def __call__(self, *args, **kwargs):#重新定义call方法
raise TypeError('This class can not instantiate directly!')
class Spam(metaclass=NoInstance):#该类不可以创建对象
@staticmethod
def grok(x):
print('Spam.grok')
Spam.grok(1)
'''
Spam.grok
'''
s = Spam()
'''
Traceback (most recent call last):
File "F:/PycharmProjects/class_obj/class_one.py", line 1016, in <module>
s = Spam()
File "F:/PycharmProjects/class_obj/class_one.py", line 1008, in __call__
raise TypeError('This class can not instantiate directly!')
TypeError: This class can not instantiate directly!
'''
假如我们想要去创建单例模式(即一个类只能创建一个对象),使用如上方法就很直接了:
class Single(type):
def __init__(self,*args,**kwargs):
self.__instance = None
super(Single, self).__init__(*args,**kwargs)
def __call__(self, *args, **kwargs):
if self.__instance is None:
self.__instance = super(Single, self).__call__(*args,**kwargs)
return self.__instance
else:
return self.__instance
class Spam(metaclass=Single):
def __init__(self):
print('Creating Spam')
a = Spam()
b = Spam()
c = Spam()
print(a is b)#True
print(b is c)#True
print(c is a)#True