我一直在继承Python的随机数生成器,以生成一个不重复结果的生成器(它将用于为模拟器生成唯一的id)而我只是在测试它是否在从预先状态加载后的行为是否一致
在人们问之前:
super(nrRand,self).__init__()
)以下是我的测试代码:
def test_stateSavingConsitantcy(self):
start = int(self.r.random())
for i in xrange(start):
self.r.random()
state = self.r.getstate()
next = self.r.random()
self.r.setstate(state)
nnext = self.r.random()
self.assertEqual(next, nnext, "Number generation not constant got {0} expecting {1}".format(nnext,next))
可以提供的任何帮助都非常感谢
编辑:
这是我要求的子类
class Singleton(type):
_instances = {}
def __call__(self, *args, **kwargs):
if self not in self._instances:
self._instances[self] = super(Singleton,self).__call__(*args,**kwargs)
return self._instances[self]
class nrRand(Random):
__metaclass__ = Singleton
'''
classdocs
'''
def __init__(self):
'''
Constructor
'''
super(nrRand,self).__init__()
self.previous = []
def random(self):
n = super(nrRand,self).random()
while n in self.previous:
n = super(nrRand,self).random()
self.previous.append(n)
return n
def seed(self,x):
if x is None:
x = long(time.time()*1000)
self.previous = []
count = x
nSeed = 0
while count < 0:
nSeed = super(nrRand,self).random()
count -= 1
super(nrRand,self).seed(nSeed)
while nSeed < 0:
super(nrRand,self).seed(nSeed)
count -= 1
def getstate(self):
return (self.previous, super(nrRand,self).getstate())
def setstate(self,state):
self.previous = state[0]
super(nrRand,self).setstate(state[1])
答案 0 :(得分:2)
getstate
和setstate
仅操纵Random
班级所知的状态;两种方法都不知道您还需要回滚先前生成的数字集。您正在回滚从Random
继承的状态,但随后该对象看到它已经生成了下一个数字并跳过它。如果您希望getstate
和setstate
正常工作,则必须覆盖它们以设置已生成数字集的状态。
更新:
def getstate(self):
return (self.previous, super(nrRand,self).getstate())
这不应该直接使用self.previous
。由于您没有制作副本,因此您将返回用于跟踪已生成数字的实际对象。当RNG产生新号码时,getstate
返回的状态反映新号码。您需要复制self.previous
,如下所示:
def getstate(self):
return (self.previous[:], super(nrRand, self).getstate())
我还建议您在setstate
:
def setstate(self, state):
previous, parent_state = state
self.previous = previous[:]
super(nrRand, self).setstate(parent_state)