Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I pass a random number generating function into a Python class?

Tags:

python

random

I'd like to be able to pass a random number generator into a class in Python. The class represents a research simulation in which a certain set of variables is initialized with draws from a Beta distribution which can be produced with random.betavariate(2,2) but I'd like to allow future users to plug in a different type of random number generating function as they please, such as random.uniform(0,1).

When I try to initialize this like so...

class simulation:
  def __init__(self,rng):
    self._rng = rng

s = simulation(random.betavariate(2,2))

...the error is that instead of passing the function itself, I'm passing one freshly-generated random number.

>>> s._rng
0.5013004813544717
>>> s._rng
0.5013004813544717

So simple question: how do I pass my favorite random number generating function with specified parameters into a class, store it in a variable, and call it when i want it? Preferably without expecting users of my class to (re)write the functions in the random module.

like image 681
workerjoe Avatar asked Dec 11 '22 04:12

workerjoe


2 Answers

Use partial from functools to bind the arguments and get a new function-like object back that you can invoke or give as an argument to the class.

>>> from functools import partial
>>> import random
>>> r = partial(random.betavariate, 2, 2)
>>> r()
0.7961360011285323
>>> r()
0.15143718490838257
like image 141
MatsLindh Avatar answered Jan 18 '23 22:01

MatsLindh


The function is called random.betavariate. When you do random.betavariate(2, 2), you're calling it with arguments. You then pass the result of this call (a number) to simulation.

If you want to pass the function itself, just pass it:

s = simulation(random.betavariate)

If you want to also pass the arguments, you'll have to do that separately (and set your class up so it knows where to find those arguments).

You could also pass an ad-hoc function that wraps your desired arguments into the call, e.g.:

s = simulation(lambda: random.betavariate(2, 2))

This passes a zero-argument function that, when called, calls random.betavariate(2, 2).

like image 35
BrenBarn Avatar answered Jan 18 '23 22:01

BrenBarn