有没有一种很好的方法来共享模块之间的随机种子(在python中)?

时间:2016-03-30 09:02:32

标签: python random seed globals

我有一个包含不同主文件的项目(针对不同的模拟)。 当我运行其中一个主文件时,它应该将种子设置为random(和numpy.random),并且项目中的所有模块都应该使用该种子。

我没有找到一个很好的方法来做到这一点。我有一个文件globals.py:

import random

myRandom=None


def initSeed(seed):
    global myRandom
    myRandom =random.Random(seed)

然后从一个主要的我做:

if __name__ == "__main__":

    seed=10
    globals.initSeed(seed)
...

然后在主要调用的模块中,我这样做:

from globals import myRandom

但myRandom在模块中的值为None(即使我在main中修改了它!)。为什么,以及如何解决它?有更好的方式吗?

2 个答案:

答案 0 :(得分:4)

我使用文件来避免global并将数据和逻辑分开。

<强> seed_handler.py

# file that stores the shared seed value 
seed_val_file = "seed_val.txt"

def save_seed(val, filename=seed_val_file):
    """ saves val. Called once in simulation1.py """
    with open(filename, "wb") as f:
        f.write(str(val))

def load_seed(filename=seed_val_file):
    """ loads val. Called by all scripts that need the shared seed value """
    with open(filename, "rb") as f:
        # change datatype accordingly (numpy.random.random() returns a float)
        return int(f.read())

<强> simulation1.py

import random
import seed_handler

def sim1():
    """ creates a new seed and prints a deterministic "random" number """
    new_seed = int("DEADBEEF",16) # Replace with numpy.random.random() or whatever
    print "New seed:", new_seed
    # do the actual seeding of the pseudo-random number generator
    random.seed(new_seed)
    # the result
    print "Random:  ", random.random()
    # save the seed value so other scripts can use it
    seed_handler.save_seed(new_seed)

if __name__ == "__main__":
    sim1()

<强> simulation2.py

import random
import seed_handler

def sim2():
    """ loads the old seed and prints a deterministic "random" number """
    old_seed = seed_handler.load_seed()
    print "Old seed:", old_seed
    # do the actual seeding of the pseudo-random number generator
    random.seed(old_seed)
    # the result
    print "Random:  ", random.random()

if __name__ == "__main__":
    sim2()

输出:

user@box:~/$ python simulation1.py 
New seed: 3735928559
Random:   0.0191336454935

user@box:~/$ python simulation2.py 
Old seed: 3735928559
Random:   0.0191336454935

附录

我刚刚在评论中读到这是用于研究的。此时,执行simulation1.py会覆盖存储的种子值;这可能不太可取。可以添加以下功能之一:

  1. 另存为json并加载到字典;那没什么 将被覆盖,每个种子值都可以有笔记,时间戳和 用户生成的与之关联的标签。
  2. 只是提示用户输入是/否来覆盖 现有价值。

答案 1 :(得分:1)

  1. 如@jDo在评论中所述,将globals.py重命名为randGlobal.py

  2. 添加了一个模块testResult.py进行测试。

  3. randGlobal.py

    import random
    
    def initSeed(seed):
        # declare
        global myRandom
        myRandom = random.Random(seed)
    

    testResult.py

    import randGlobal
    
    def randOutput():
        return randGlobal.myRandom.random()
    

    main.py

    import randGlobal
    
    # Add a module for testing
    import testResult
    
    
    def test():
        result = testResult.randOutput()
        print result
    
    
    # main
    if __name__ == "__main__":
    
        seed=10
        randGlobal.initSeed(seed)
        # after init, hava a test
        test()