Random.Random subclassing problem (python / CPython 2.6)

I tried this piece of code in CPython 2.6 (original python implementation):

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() 

Although this is similar to CORRECT python inheritance, it causes 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): 

a

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

everything will be miraculously "right" .. but the first random numbers generated will always be the same for all Uniform instances (due to the same seed!).

SOURCE OF THE PROBLEM

The class of the class is random.Random class of the class of the IS class and, of course, this is NOT the base class (see / usr / lib / python2.6 / random.py on Unix and its equivalent in Win). So hacking subclasses of built-in classes will be in our course. The random.Random class - despite its subclasses of the nature of the new style in the first class, written in C (in / usr / lib / python2.6 / random.py see import _random - and this is a built-in class!).

What does it mean? We need to override the __new__ method as if it were embedded in the class (more details here: the problem with the subclass of the built-in type ).

FINAL WORK IN SHORT

Just add an override of the __new__ method (that random() was imported into the second line of this “question” and just the object is passed backstage to random.Random.seed(x) to initialize the object's seed (in the source / usr / lib / python 2.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 random number generator Mersenne Twister in Python ;-) Good LUCK!

+4
source share
1 answer

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 ; Random extension should be sufficient.

0
source

Source: https://habr.com/ru/post/1341714/


All Articles