非常感谢您迄今为止给我的建议。使用测试平台是这个论坛真正向我展示的亮点,因为我很感激。我的问题是我正在玩一个单身人士,通常我不会对它进行分析,但在测试平台中我需要这样做。所以有人能告诉我如何去做这件事吗?我已经开始使用basic example并将其构建到测试平台中,以便我可以看到最新情况。现在我不知道怎么摆脱它!
非常感谢!!
import sys
import logging
import unittest
LOGLEVEL = logging.DEBUG
class Singleton:
""" A python singleton """
class __impl:
""" Implementation of the singleton interface """
def __init__(self):
self.log = logging.getLogger()
self.log.debug("Init %s" % self.__class__.__name__)
def id(self):
""" Test method, return singleton id """
return id(self)
# storage for the instance reference
__instance = None
def __init__(self):
""" Create singleton instance """
# Check whether we already have an instance
if Singleton.__instance is None:
# Create and remember instance
Singleton.__instance = Singleton.__impl()
# Store instance reference as the only member in the handle
self.__dict__['_Singleton__instance'] = Singleton.__instance
def __getattr__(self, attr):
""" Delegate access to implementation """
return getattr(self.__instance, attr)
def __setattr__(self, attr, value):
""" Delegate access to implementation """
return setattr(self.__instance, attr, value)
class A:
def __init__(self):
self.log = logging.getLogger()
self.log.debug("Init %s" % self.__class__.__name__)
self.lowclass = Singleton()
self.id = self.lowclass.id()
self.log.debug("ID: %s" % self.id)
class B:
def __init__(self):
self.log = logging.getLogger()
self.log.debug("Init %s" % self.__class__.__name__)
self.lowclass = Singleton()
self.id = self.lowclass.id()
self.log.debug("ID: %s" % self.id)
class ATests(unittest.TestCase):
def testOne(self):
a = A()
aid = a.id
b = B()
bid = b.id
self.assertEqual(a.id, b.id)
#
# How do I destroy this thing??
#
del a
del b
a1 = A()
a1id = a1.id
self.assertNotEqual(a1id, aid)
if __name__ == '__main__':
# Set's up a basic logger
logging.basicConfig( format="%(asctime)s %(levelname)-8s %(module)s %(funcName)s %(message)s",
datefmt="%H:%M:%S", stream=sys.stderr )
log = logging.getLogger("")
log.setLevel(LOGLEVEL)
#
suite = unittest.TestLoader().loadTestsFromTestCase(ATests)
sys.exit(unittest.TextTestRunner(verbosity=LOGLEVEL).run(suite))
答案 0 :(得分:7)
作为Borg的作者,我显然是第二个@mjv的评论,但是,无论是Borg(又名“monostate”)还是Highlander(又名“singleton”),你都需要添加一个“drop everything”方法来支持{{1}在你的测试套件中。使用单个前导下划线命名此类方法会告诉sw的其他部分不要单独使用,但测试是非典型的野兽,并且通常需要使用其他内部属性进行捣乱。
因此,针对您的具体情况,
tearDown
同样,对于Borg,class Singleton:
...
def _drop(self):
"Drop the instance (for testing purposes)."
Singleton.__instance = None
del self._Singleton__instance
方法会释放并清除共享字典并将其替换为全新字典。
答案 1 :(得分:0)
考虑到你将拥有很多这样的课程,我不会把它们称为单身。您只需将属性推迟到单例类。确保班级实际上是一个单身人士似乎更好。
你的解决方案的问题是你必须同时实现 del 方法(这很好),还要实现一个引用计数器,这看起来不错。 : - )
以下是几个实现的问题:Is there a simple, elegant way to define singletons?
哪一个适合你取决于你想要的单身人士。每个特定值一个对象,但对于任何值?一组预定义的单身人士?一个合适的单身人士,即只有一个单一的对象?