I have tried this code snippet in CPython 2.6 (original python implementation):
from random import Random, random
class Uniform(Random, object):
def __init__(self, min, max):
self._min =min
se开发者_开发知识库lf._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()
Although it seems to be CORRECT pythonic inheritance, it throws this error:
/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>
But if you define
def __init__(self, min, max):
as
def __init__(self, (min, max)):
things will miraculously go on "correctly".. but the first generated random numbers will be always the same for all instances of Uniform (because of the same initial seed!).
PROBLEM SOURCE
The random.Random
class IS new-style class and definitely it is NOT basic class (see /usr/lib/python2.6/random.py on Unix and its equivalent on Win). So hacks about subclassing of built-in classes -- will be in our course. The random.Random
class -- despite of its new-style nature subclasses at first class written in C (in /usr/lib/python2.6/random.py see import _random
-and it is built-in class!).
What does it mean? We need to override __new__
method as if it was builtin class itself (more here: problem subclassing builtin type).
FINAL WORKAROUND IN SHORT
Just add overriding of __new__
method (that random()
was imported in the 2nd line of this "question" and is just object passed behind the scene to random.Random.seed(x)
to initialize the object seed (in source of /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
Enjoy the built-in Mersenne Twister random number generator in Python ;-) Good LUCK!
You need to call Random.__init__(self, seed)
at the beginning of your constructor (the seed
argument is optional):
def __init__(self, min, max):
Random.__init__(self) # Use the default seed.
self._min =min
self._max =max
Also, I don't quite understand why you are explicitly extending object
as well; extending Random
should suffice.
精彩评论