You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

继承random.Random类后同种子生成不同随机结果的问题

问题:重写random.Random的random()方法为何改变随机序列?

初始代码与预期输出

当我们直接继承random.Random且不修改任何方法时,相同种子会生成一致的随机序列:

import random

class MyRandom(random.Random):
    pass

r = random.Random()
r.seed(10)
print(r.randint(0, 20))
print(r.randint(0, 20))
print(r.randint(0, 20))

print("------------")

r2 = MyRandom()
r2.seed(10)
print(r2.randint(0, 20))
print(r2.randint(0, 20))
print(r2.randint(0, 20))

输出:

18
1
13
------------
18
1
13

修改后的代码与意外输出

但当我们重写random()方法(哪怕只是调用父类的实现),相同种子的随机序列却发生了变化:

import random

class MyRandom(random.Random):
    def random(self):
        return super().random()

r = random.Random()
r.seed(10)
print(r.randint(0, 20))
print(r.randint(0, 20))
print(r.randint(0, 20))

print("------------")
r2 = MyRandom()
r2.seed(10)
print(r2.randint(0, 20))
print(r2.randint(0, 20))
print(r2.randint(0, 20))

输出:

18
1
13
------------
20
9
6

原因解释

这是CPython中random.Random的内部实现逻辑导致的:

  • randint方法底层依赖randrange,而randrange有两种生成随机数的路径:
    1. 如果子类没有重写random(),会优先使用_getrandbits方法来生成随机数,这个路径的状态流转和父类完全一致,所以相同种子输出相同序列。
    2. 一旦子类重写了random(),哪怕只是简单转发父类的实现,CPython会默认子类可能未正确实现配套的_getrandbits方法,于是randrange会切换到另一种基于random()的实现逻辑——这个逻辑的随机数生成步骤和_getrandbits路径不同,哪怕种子相同,最终输出的序列也会不一样。

而直接调用random()时,不管有没有重写,都是直接调用父类的random()方法,状态流转完全一致,所以输出不会有差异。

内容的提问来源于stack exchange,提问作者MarcTheSpark

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 17:20:14