Python构造函数参数不是随机的bug?

时间:2012-08-26 02:16:13

标签: python random

我刚刚发现了这个奇怪的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 个答案:

答案 0 :(得分: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'

这样,我们将随机化转移到函数本身,而不是在函数定义时。

答案 1 :(得分:4)

在python中,默认参数初始化一次。所以你反复得到相同的值,因为这是默认参数初始化时的值。见http://www.deadlybloodyserious.com/2008/05/default-argument-blunders/

答案 2 :(得分:3)

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

答案 3 :(得分:1)

Python constructor does weird things with optional parameters

中的原因相同

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

解决此问题:

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