4

私は最近、この奇妙な Python の「バグ」を見つけたので、誰か詳しく知っているかどうか知りたいと思いました!

たとえば、python モジュールを使用します。

import random

class SaySomething:
    def __init__(self, value=random.randint(1, 3)):
        if value == 1: print 'one'
        elif value == 2: print 'two'
        elif value == 3: print 'three'

a = 0

while a < 10:
    SaySomething()
    a += 1

このコードは、何らかの理由で同じ番号を 10 回出力します!!! 今、これは私にはわかりません。コンストラクターが同じ値で 10 回連続して呼び出されているようです。しかし、それぞれを印刷するSaySomething()と、それらはすべて異なるポインター アドレスを持っていることがわかります。したがって、それらは同じオブジェクトではありません。

変更した場合:

SaySomething()

SaySomething(random.randint(1, 3))

実際のランダムな選択が行われ、期待どおりに実行されます。

なぜこれが起こるのか知っている人はいますか?

4

4 に答える 4

13

問題は、Python のデフォルト引数が、関数の作成時に 1 回評価されることです。これを修正するには、次を試してください。

    def __init__(self, value = None):
        if value is None:
             value = random.randint(1, 3)

        if value == 1: print 'one'
        elif value == 2: print 'two'
        elif value == 3: print 'three'

このようにして、ランダム化を関数定義時ではなく、関数自体にシフトします。

于 2012-08-26T02:20:20.693 に答える
4

Python では、デフォルトの引数は一度初期化されます。デフォルトの引数が初期化されたときの値であるため、同じ値を何度も取得しています。http://www.deadlybloodyserious.com/2008/05/default-argument-blunders/を参照してください。

于 2012-08-26T02:18:39.850 に答える
3

これは、クラスがコンパイルまたは解釈されると、 variable の値valueが に設定されrandom.randint(1, 3)、他の値を渡すまで変更されないためです。

于 2012-08-26T02:22:42.283 に答える
1

Pythonコンストラクターと同じ理由で、オプションのパラメーターで奇妙なことをします

オプションの引数のデフォルト値は単一のインスタンスであるため、作成されるすべてのインスタンスに対して 1 回だけ計算されます。

これを修正するには:

import random 
class saySomething: 
    def __init__(self, value = None):
        random_value = random.randint(1, 3) if value == None else value
        if random_value in [1, 2, 3] print ['one', 'two', 'three'][random_value - 1]

for a in xrange(10):
    saySomething() 
于 2012-08-26T02:21:32.673 に答える