2016-03-30 20 views
6

Ich habe ein Projekt mit verschiedenen Hauptdateien (für verschiedene Simulationen). Wenn ich eine der Hauptdateien ausführe, sollte es einen Zufallswert (und numpy.random) setzen, und alle Module im Projekt sollten diesen Samen verwenden.Gibt es eine gute Möglichkeit, den Samen der zufälligen zwischen Modulen (in Python) zu teilen?

Ich finde keinen guten Weg, dies zu tun. Ich habe eine Datei globals.py mit diesem:

import random 

myRandom=None 


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

dann von einem Haupt ich tun:

if __name__ == "__main__": 

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

Dann in den Modulen, die Haupt Anrufe, ich mache:

from globals import myRandom 

Aber myRandom hat den Wert None im Modul (obwohl ich es in main geändert habe!). Warum und wie man es repariert? Gibt es einen schöneren Weg?

+3

Wenn Sie wollen, es zu tun, indem 'global' verwenden, sollte die Variable' global' in allen Funktionen deklariert werden, die es verwenden. Sie könnten Klassen und Unterklassen verwenden, aber Sie könnten auch den Wert in eine Datei schreiben. Ich denke, Sie würden in Ihrem aktuellen Setup auf die Variable "myRandom" über "globals.myRandom" zugreifen. Übrigens. 'globals' ist bereits in Python definiert, also ändere den Dateinamen in etwas anderes (nicht' glob' - auch übernommen) – jDo

+0

'sollte es einen Zufallswert setzen und alle Module im Projekt sollten diesen Seed verwenden. Sound wie du bist Suchen nach Singletons? – Cyrbil

+1

Ich frage mich nur, was ist Ihr Anwendungsfall – yedpodtrzitko

Antwort

1
  1. Wie @jDo in Kommentar erwähnt, umbenannt globals.py in randGlobal.py.

  2. Ein Modul testResult.py zum Testen hinzugefügt.


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() 
4

ich eine Datei verwenden würde 01.235.309 zu vermeidenund um Daten und Logik ein wenig zu trennen.

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() 

Ausgang:

[email protected]:~/$ python simulation1.py 
New seed: 3735928559 
Random: 0.0191336454935 

[email protected]:~/$ python simulation2.py 
Old seed: 3735928559 
Random: 0.0191336454935 

NACHTRAG

ich nur in den Kommentaren gelesen, dass dies für die Forschung ist. Momentan überschreibt die Ausführung von simulation1.py den gespeicherten Startwert; Dies ist möglicherweise nicht wünschenswert. Man könnte eines dieser Merkmale hinzufügen:

  1. als json speichern und ins Wörterbuch laden; auf diese Weise würde nichts überschrieben werden und jeder Seed-Wert könnte Notizen, einen Zeitstempel und ein benutzergeneriertes Label haben, das damit verknüpft ist.
  2. einfach den Benutzer auffordern, für eine ja/nein die vorhandenen Wert zu überschreiben.
+2

Es scheint mir, dass dies eine besonders gute Idee, da die OP erwähnt sie diese Zwecke für die Forschung tun. Sie sollten wahrscheinlich die Samen in einer dauerhaftere Art und Weise als eine globale Variable werden Speicherung, falls sie müssen einen Lauf replizieren oder ihr Modell zu erweitern. – Paul

+0

@ Paul \t \t Danke, ich glaube, du hast Recht. Eigentlich könnte die ganze Idee, Werte zu überschreiben, in diesem Zusammenhang unklug sein. Der Gedanke, das Zufallsmodul zurückentwickeln zu müssen, um herauszufinden, welcher Seed-Wert eine gegebene Ausgabe erzeugt, ist sicherlich nicht attraktiv. – jDo