- 1. 假设你不想任何人创建这个类的实例
- 链接]">2. 假如你想实现单例模式 [链接]
- 3. 元类实现缓存实例
你想通过改变实例创建方式来实现单例、缓存或其他类似的特性。
如果你想自定义这个步骤,你可以定义一个元类并自己实现 call() 方法。
1. 假设你不想任何人创建这个类的实例
class NoInstances(type):def __call__(self, *args, **kwargs):raise TypeError("Can't instantuate directly")class Spam(metaclass=NoInstances):@staticmethoddef grok(x):print('Spam.grok')Spam.grok(42)# Spam.groks = Spam()# TypeError: Can't instantuate directly
2. 假如你想实现单例模式 [链接]
class Singleton(type):def __init__(self, *args, **kwargs):self.__instance = Nonesuper().__init__(*args, **kwargs)def __call__(self, *args, **kwargs):if self.__instance is None:self.__instance = super().__call__(*args, **kwargs)return self.__instanceelse:return self.__instanceclass Spam(metaclass=Singleton):def __init__(self):print('Creating Spam')a = Spam()b = Spam()print(a is b)# Truec = Spam()print(a is c)# True
3. 元类实现缓存实例
import weakrefclass Cached(type):def __init__(self, *args, **kwargs):super().__init__(*args, **kwargs)self.__cache = weakref.WeakValueDictionary()def __call__(self, *args):if args in self.__cache:return self.__cache[args]else:obj = super().__call__(*args)self.__cache[args] = objreturn objclass Spam(metaclass=Cached):def __init__(self, name):print('Creating Spam({!r})'.format(name))self.name = namea = Spam('Guido')# Creating Spam('Guido')b = Spam('Diana')# Creating Spam('Diana')c = Spam('Guido')# Cachedprint(a is b)# Falseprint(a is c)# True
