我认为这个想法是当给定一个起始种子时,对bar() 的调用应该总是看到相同的随机数序列;不管中间插入了多少对foo()的调用。
我们可以通过从随机状态创建一个随机种子来做到这一点,当临时播种状态完成时,我们使用该随机种子重新播种。这可以包装在上下文管理器中:
import numpy as np
class temporary_seed:
def __init__(self, seed):
self.seed = seed
self.backup = None
def __enter__(self):
self.backup = np.random.randint(2**32-1, dtype=np.uint32)
np.random.seed(self.seed)
def __exit__(self, *_):
np.random.seed(self.backup)
让我们试试这个
def bar():
print('bar:', np.random.randint(10))
def foo():
print('foo:', np.random.randint(10))
np.random.seed(999)
bar() # bar: 0
with temporary_seed(42):
foo() # foo: 6
foo() # foo: 3
bar() # bar: 9
所以我们得到 bar-sequence [0, 9] 和 foo-sequence [6, 3]。
我们在不重新全局播种的情况下重试:
bar() # bar: 1
with temporary_seed(42):
foo() # foo: 6
foo() # foo: 3
bar() # bar: 2
新的 bar-sequence [1, 2] 和相同的 foo-sequence 再次 [6, 3]。
再次使用相同的全局种子,但 foo 的种子不同:
np.random.seed(999)
bar() # bar: 0
with temporary_seed(0):
foo() # foo: 5
bar() # bar: 9
这次我们再次得到第一个 bar-sequence [0, 9] 和一个不同的 foo。不错!
那么问题在哪里?通过进入和离开临时种子部分,我们改变了随机状态。我们这样做是确定性的,结果是可重复的,但是如果我们不调用输入temorary_seed,则得到不同的序列:
np.random.seed(999)
bar() # bar: 0
bar() # bar: 5
条形序列 [0, 5] 而不是 [0, 9]。如果您可以忍受这种限制,那么这种方法应该可行。