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 では同等のものを参照してください)。したがって、組み込みクラスのサブクラス化に関するハックは、コースに含まれます。クラス --そのrandom.Random新しいスタイルの性質にもかかわらず、C で書かれた最初のクラスのサブクラス(/usr/lib/python2.6/random.py を参照してくださいimport _random- そしてそれは組み込みクラスです!)。

どういう意味ですか?メソッドを組み込みクラス自体であるかのようにオーバーライドする必要があります__new__(詳細はこちら:組み込み型のサブクラス化の問題)。

要するに最終的な回避策

__new__メソッドのオーバーライドを追加するだけです(random()これはこの「質問」の2行目にインポートされ、オブジェクトシードを初期化するために舞台裏で渡された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 に答える