Maxareo
Maxareo

Reputation: 275

How does a random seed work in a function factory in Python?

Suppose I want to generate a bunch of binary number generators given the success probabilities. One concern I have is about the random seed. The random seeds for f1, f2, f3 are their creation time, right? And the seeds are fixed for each function regardless of the random seed in the global namespace, right?

def f(p):
    import random, time
    random.seed(time.time())
    def g():
        return 1 if random.random() < p else 0
    return g

f1 = f(0.05)
f2 = f(0.65)
f3 = f(0.25)

Upvotes: 1

Views: 2749

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1124748

You pass in a seed to the global random object each time you call f(), because all top-level functions in the random module feed into a singleton object. This means that by the time f3 is created, the seeds set in f2 and f1 have been superseded, the seeds are not independent from the global random object. Importing random again for each f() call does not give you a new state, as really only binds names anew each time once the module object itself is loaded (only on the first import).

If you want to have a seeded random generator per function, you need to create individual random.Random() instances:

import random
import time

def f(p):
    seeded_random = random.Random(time.time())
    def g():
        return 1 if seeded_random.random() < p else 0
    return g

From the random module documentation:

The functions supplied by this module are actually bound methods of a hidden instance of the random.Random class. You can instantiate your own instances of Random to get generators that don’t share state.

Upvotes: 3

Related Questions