#!/usr/bin/env python # -*- encoding: utf-8 -*- """ Topic: 创建缓存实例 Desc : """ import logging a = logging.getLogger('foo') b = logging.getLogger('bar') print(a is b) c = logging.getLogger('foo') print(a is c) # The class in question class Spam: def __init__(self, name): self.name = name # Caching support import weakref _spam_cache = weakref.WeakValueDictionary() def get_spam(name): if name not in _spam_cache: s = Spam(name) _spam_cache[name] = s else: s = _spam_cache[name] return s # Note: This code doesn't quite work class Spam1: _spam_cache = weakref.WeakValueDictionary() def __new__(cls, name): print('Spam1__new__') if name in cls._spam_cache: return cls._spam_cache[name] else: self = super().__new__(cls) cls._spam_cache[name] = self return self def __init__(self, name): print('Initializing Spam') self.name = name s = Spam1('Dave') t = Spam1('Dave') print(s is t) class CachedSpamManager: def __init__(self): self._cache = weakref.WeakValueDictionary() def get_spam(self, name): if name not in self._cache: s = Spam(name) self._cache[name] = s else: s = self._cache[name] return s def clear(self): self._cache.clear() class Spam2: manager = CachedSpamManager() def __init__(self, name): self.name = name def get_spam(name): return Spam2.manager.get_spam(name) # ------------------------最后的修正方案------------------------ class CachedSpamManager2: def __init__(self): self._cache = weakref.WeakValueDictionary() def get_spam(self, name): if name not in self._cache: temp = Spam3._new(name) # Modified creation self._cache[name] = temp else: temp = self._cache[name] return temp def clear(self): self._cache.clear() class Spam3: def __init__(self, *args, **kwargs): raise RuntimeError("Can't instantiate directly") # Alternate constructor @classmethod def _new(cls, name): self = cls.__new__(cls) self.name = name return self print('------------------------------') cachedSpamManager = CachedSpamManager2() s = cachedSpamManager.get_spam('Dave') t = cachedSpamManager.get_spam('Dave') print(s is t)