如何将随机数生成函数传递给Python类?

4 投票
3 回答
3572 浏览
提问于 2025-04-18 17:12

我想在Python中把一个随机数生成器传入一个类。这个类代表一个研究模拟,其中一些变量是通过从Beta分布中抽取的值来初始化的,这个Beta分布可以用random.betavariate(2,2)来生成。但我希望将来使用这个类的人可以根据自己的需要插入不同类型的随机数生成函数,比如random.uniform(0,1)

当我尝试这样初始化的时候……

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

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

……出现的错误是,我传入的不是函数本身,而是一个新生成的随机数。

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

所以我有个简单的问题:我该如何把我喜欢的随机数生成函数和指定的参数传入一个类,存储在一个变量中,然后在需要的时候调用它?最好是让使用我这个类的人不需要(重新)编写random模块中的函数。

3 个回答

0

也许可以用闭包?

>>> class simulation(object):
...     def __init__(self, rng):
...         self.rng = rng
... 
>>> def f(func, *args):
...     def ret():
...         return func(*args)
...     return ret
...
>>> bar = f(random.randint, 0, 9)
>>> s = simulation(bar)
>>> s.rng()
6
>>> s.rng()
3
>>> s.rng()
9
>>> s.rng()
1
>>> 

不过,来自 functoolspartial 看起来更自然一些。

8

使用来自 functoolspartial,可以把一些参数固定住,然后得到一个新的像函数一样的对象。你可以调用这个对象,或者把它作为参数传给其他类。

>>> from functools import partial
>>> import random
>>> r = partial(random.betavariate, 2, 2)
>>> r()
0.7961360011285323
>>> r()
0.15143718490838257
5

这个函数叫做 random.betavariate。当你使用 random.betavariate(2, 2) 时,你是在给它传递参数。然后,你把这个调用的结果(一个数字)传给 simulation

如果你想传递函数本身,只需直接传递它:

s = simulation(random.betavariate)

如果你还想传递参数,就得单独处理这些参数(并且要设置你的类,让它知道去哪里找这些参数)。

你也可以传递一个临时函数,把你想要的参数包裹在调用里面,比如:

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

这个做法是传递一个不带参数的函数,当它被调用时,会执行 random.betavariate(2, 2)

撰写回答