4

我在 CPython 2.6(原始 python 实现)中尝试了这个代码片段:

from random import Random, random

class Uniform(Random, object):
    def __init__(self,  min,  max):
        self._min =min
        self._max =max
    def randint(self):
        return super(Uniform, self).randint (self._min,  self._max)
    def uniform(self):
        return super(Uniform, self).uniform(self._min,  self._max)

if __name__ == '__main__':
    a=Uniform(0.,  1.2)
    print a.uniform()
    print a.randint()

尽管它似乎是正确的pythonic 继承,但它会引发此错误:

/tmp/source.py in <module>()
     11 
     12 if __name__ == '__main__':
---> 13   a=Uniform(0.,  1.2)
     14   print a.uniform()
     15   print a.randint()

TypeError: seed expected at most 1 arguments, got 2
WARNING: Failure executing file: </tmp/source.py>

但是如果你定义

def __init__(self,  min,  max):

作为

def __init__(self,  (min,  max)):

事情会奇迹般地“正确”地进行……但是对于 Uniform 的所有实例,第一个生成的随机数将始终相同(因为相同的初始种子!)。

问题根源

该类random.Random是新式类,绝对不是基本类(参见 Unix 上的 /usr/lib/python2.6/random.py 和 Win 上的等价物)。因此,关于内置类的子类化的技巧——将在我们的课程中。该类——尽管它是用 C 编写的第一类random.Random的新型自然子类(在 /usr/lib/python2.6/random.py 中看到——它是内置类!)。import _random

这是什么意思?我们需要重写__new__方法,就好像它是内置类本身一样(更多信息:问题子类化内置类型)。

简短的最终解决方法

只需添加方法的覆盖__new__random()在此“问题”的第二行中导入,只是在场景后面传递random.Random.seed(x)的对象以初始化对象种子(在 /usr/lib/python2.6/random.py 的源代码中)) .

class Uniform(Random, object):
    def __new__(cls, *args, **kwargs):
        return super (Uniform, cls).__new__ (cls, random() )
    def __init__(self,  min,  max):
        self._min =min
        self._max =max

享受 Python 中内置的 Mersenne Twister 随机数生成器 ;-) 祝你好运!

4

1 回答 1

0

您需要Random.__init__(self, seed)在构造函数的开头调用(seed参数是可选的):

def __init__(self,  min,  max):
    Random.__init__(self)  # Use the default seed.
    self._min =min
    self._max =max

另外,我不太明白您为什么还要明确扩展object;扩展Random应该足够了。

于 2011-02-28T22:16:26.043 回答