2011-02-02 15 views
7

Necesito asegurarme de que toda la aleatoriedad en mi programa sea completamente replicable. ¿Dónde debo hacer una llamada a random.seed()?python 3: random.seed(): ¿dónde llamarlo?

Pensé que debería estar en mi módulo main.py, pero importa otros módulos que usan funciones aleatorias.

Puedo navegar cuidadosamente a través de mis importaciones para ver cuál es la primera en ejecutar, pero en el momento en que cambie la estructura de mi código tendré que recordar volver a hacer este análisis.

¿Existe alguna solución simple y segura?

+0

¿Le preocupa que los módulos que usan funciones aleatorias alteren la replicabilidad? Siempre que no usen random.seed() ellos mismos, debería estar bien. Si esa no es tu preocupación, ¿por qué estás preocupado por lo que hacen tus módulos? –

+0

¿Está diciendo que no tiene una función 'principal()' de nivel superior que hace el trabajo real de la aplicación? Por qué no? –

+1

@Josh @S Lott: Tengo 'main'; comienza diciendo: 'import random',' import another module', 'random.random.seed()'. Es solo que 'anothermodule' pasa a 'import random' y usa funciones de 'random', por lo que mi siembra ocurre un poco tarde. – max

Respuesta

7

En realidad, es seguro ejecutar código en la "sección de importación" de su módulo principal, por lo que si no está seguro acerca de importar otros módulos que podrían o no usar el módulo aleatorio, puede omitir su semilla, por supuesto usar algo como

import random 
random.seed(seed_value) 

import something 
import else 

if __name__ == "__main__": 
    main() 
1

Puede rodar su propio singleton que encapsula al azar. A continuación, puede usar Python documentation on random getstate y setstate para cambiar el estado del generador de números aleatorios. Eso le daría a su programa dos generadores de números aleatorios esencialmente.

+0

En lugar de random.random(), considere hacer un "singleton" de una instancia random.WichmannHill, y usar eso en todo el código que necesita tener resultados reproducibles. Todos los demás módulos que invocan random.random() pueden seguir haciéndolo sin que te importe o no lo sepas. – nos

4

Si desea azar para ser replicables, es probable que sea posible para que una instancia de random.Random en su solicitud, llame seed() en esa instancia, y utilizar esa instancia para que los números aleatorios.

random.random() en realidad usa un singleton de la clase random.Random, por conveniencia para las personas que no les importa lo suficiente como para hacer su propia instancia de clase. Pero ese singleton se comparte potencialmente con otros módulos que pueden querer llamar al random.random() para generar números aleatorios por cualquier razón. Es por eso que en su caso es mejor que crea una instancia de su propia instancia random.Random.

Citando de the docs:

Las funciones proporcionadas por este módulo se métodos de una instancia oculta de la clase random.Random realmente unidos. Puede instanciar sus propias instancias de Random para obtener generadores que no comparten estado.