在Python3中,random.Random(seed)允许使用字节数组进行播种。
class Random(_random.Random):
...
def __init__(self, x=None):
self.seed(x)
...
def seed(self, a=None, version=2):
...
if version == 2 and isinstance(a, (str, bytes, bytearray)):
if isinstance(a, str):
a = a.encode()
a += _sha512(a).digest()
a = int.from_bytes(a, 'big')
...
尝试时
>>> random.Random().__init__(bytearray([1, 2, 3]))
或
>>> r = random.Random()
>>> r.seed(bytearray([1, 2, 3]))
它将正常工作。
但是当您尝试这样做时,结果不一致。
>>> random.Random(bytearray([1, 2, 3]))
TypeError: unhashable type: 'bytearray'
我编译并调试了python 3.7.0二进制文件,当尝试使用字节数组初始化PRNG时,它将调用Modules / _randommodule.c中的random_seed
方法,并在此处直接引发typeerror。为什么?
答案 0 :(得分:2)
该异常不是来自Random.__init__()
方法,而是来自__new__()
方法,该方法在__init__()
之前被调用:
>>> random.Random.__new__(random.Random, bytearray([1,2,3]))
TypeError: unhashable type: 'bytearray'
>>> random.Random.__new__(random.Random, bytes([1,2,3]))
<random.Random at 0x1b0cd78>
答案 1 :(得分:1)
BlackJack's answer启发了我。我仔细阅读了_random.Random.__new__
方法的C source code。
_random.Random.__new__
方法(在C中为random_new
)使用相同的参数调用_random.Random.seed
方法(在C中为random_seed
)。如果args
函数中的random_seed
包含一个非整数对象作为种子,它将尝试get the hash value该对象。因此,当对象是字节数组时,它将引发类型错误。
因此,_random.Random
并没有专门处理字节数组的种子处理,但是其子类random.Random
可以处理,这似乎是不兼容的python错误。