4

我最近刚刚发现了这个奇怪的 Python 'bug',我想看看是否有人知道更多关于它的信息!

以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 中的默认参数在创建函数时被评估一次。要解决此问题,请尝试:

    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

这是因为当类被编译或解释时,变量的值value被设置为random.randint(1, 3),并且在你向它传递一些其他值之前它不会改变。

于 2012-08-26T02:22:42.283 回答
1

出于与 Python 构造函数相同的原因,使用可选参数会做一些奇怪的事情

可选参数的默认值是单个实例,因此只为所有实例计算一次。

要解决这个问题:

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 回答