- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我对 random.random() 函数在 python 中的工作方式有点困惑。
docs说它'返回[0.0,1.0)范围内的下一个随机浮点数'。
我知道伪随机数生成器通过对一个值执行一些操作来工作。通常,此值是生成器生成的先前数字。所以我认为这就是 '下一个随机浮点' 这里的意思。 (如果我错了请纠正我)
但是当我看到source code在随机库中,随机函数未在 class Random
中定义.相反,它在 class SystemRandom
中定义如下(代码第671行):
def random(self):
"""Get the next random number in the range [0.0, 1.0)."""
return (int.from_bytes(_urandom(7), 'big') >> 3) * RECIP_BPF
最佳答案
random
python中的模块包含pseudorandom number generators(PRNGs)的两个接口(interface)(类) .您可以将其视为生成随机数的两种方式。
A note on the module
secrets
.The module
secrets
does not implement any type of PRNG but provides helper functions(which is awesome because we don't have to write them ourselves) based on SystemRandom and os.urandom(which SystemRandom is based upon). The comments are mine:from random import SystemRandom
_sysrand = SystemRandom() #secrets._sysrand
randbits = _sysrand.getrandbits #secrets.randbits
choice = _sysrand.choice #secrets.choice
def randbelow(exclusive_upper_bound): #secrets.randbelow
...
return _sysrand._randbelow(exclusive_upper_bound) #uses SystemRandom
def token_bytes(nbytes=None): #secrets.token_bytes
...
return os.urandom(nbytes)
def token_hex(nbytes=None): #secrets.token_hex(uses token_bytes())
...
return binascii.hexlify(token_bytes(nbytes)).decode('ascii')
def token_urlsafe(nbytes=None): # secrets.token_urlsafe(uses token_bytes())
...
tok = token_bytes(nbytes)
return base64.urlsafe_b64encode(tok).rstrip(b'=').decode('ascii')
_inst = Random()
...
random = _inst.random
random.Random()
没有定义
random()
方法本身,但继承
_random.Random()
(它确实定义了一个名为
random()
的方法),这是一个名为
Random()
的类位于模块
_random
.
C
_random
的源代码(它是一个内置模块)模块可以找到
here (它实际上被称为
_randommodule.c
。参见下面的解释)
Naming convention for python modules written in C/C++
(Historically, if a module is called spam, the C file containing its implementation is called spammodule.c; if the module name is very long, like spammify, the module name can be just spammify.c.)
_random.Random.random()
(或
random.random()
)方法定义为
_random_Random_random_impl()
在
_randommodule.c
文件。
static PyObject *
_random_Random_random_impl(RandomObject *self)
{
uint32_t a=genrand_int32(self)>>5, b=genrand_int32(self)>>6;
return PyFloat_FromDouble((a*67108864.0+b)*(1.0/9007199254740992.0));
}
genrand_int32()
是由
Mersenne Twister PRNG 定义的函数返回一个 4 字节数字的实现。
SystemRandom().random()
在模块
random.py
中定义.
...
def random(self):
"""Get the next random number in the range [0.0, 1.0)."""
return (int.from_bytes(_urandom(7), 'big') >> 3) * RECIP_BPF**strong text**
os.py
中定义的另一个名为 urandom() 的函数。
from os import urandom as _urandom
os.py
模块未定义函数
urandom()
本身,但从内置模块导入它。
os.py
将导入
posix
如果您在
POSIX OS 上,则内置模块或
nt
如果您在
Windows NT OS 上,则内置模块.这些模块包含 urandom() 的定义。
if 'posix' in _names:
name = 'posix'
linesep = '\n'
from posix import *
elif 'nt' in _names:
name = 'nt'
linesep = '\r\n'
from nt import *
posix
andnt
are built-in modules, so they don't have the__file__
attribute.
urandom()
is defined in theposixmodule.c
as os_urandom_impl() which calls _PyOS_URandom().
static PyObject *
os_urandom_impl(PyObject *module, Py_ssize_t size)
{
...
bytes = PyBytes_FromStringAndSize(NULL, size);
...
result = _PyOS_URandom(PyBytes_AS_STRING(bytes), PyBytes_GET_SIZE(bytes));
...
return bytes
}
_PyOS_URandom()
is defined in thebootstrap_hash.c
file which then calls pyurandom()
int
_PyOS_URandom(void *buffer, Py_ssize_t size)
{
return pyurandom(buffer, size, 1, 1);
}
pyurandom()
is defined in thebootstrap_hash.c
file which then calls dev_urandom().
static int
pyurandom(void *buffer, Py_ssize_t size, int blocking, int raise)
{
...
return dev_urandom(buffer, size, raise);
...
}
dev_urandom
is defined in thebootstrap_hash.c
file which then uses the/dev/urandom
directory to get random bytes.
static int
dev_urandom(char *buffer, Py_ssize_t size, int raise)
{
...
fd = _Py_open("/dev/urandom", O_RDONLY);
...
do {
n = _Py_read(fd, buffer, (size_t)size);
...
} while (0 < size);
...
}
It may look a bit weird(I thought that as well) but the
posixmodule.c
file is also used for the NT systems, here is a quote(comment) from the beginning of the fileThis file is also used for Windows NT/MS-Win. In that case the
module actually calls itself 'nt', not 'posix', and a few functions are either unimplemented or implemented differently. The source
assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent of the compiler used. Different compilers define their own feature test macro, e.g. '_MSC_VER'.
pyurandom()
is defined in thebootstrap_hash.c
file which then calls win32_urandom().
static int
pyurandom(void *buffer, Py_ssize_t size, int blocking, int raise)
{
...
#ifdef MS_WINDOWS
return win32_urandom((unsigned char *)buffer, size, raise);
#else
...
}
win32_urandom()
is defined in thebootstrap_hash.c
file which then callsCryptGenRandom()
.
static int
win32_urandom(unsigned char *buffer, Py_ssize_t size, int raise)
{
...
if (!CryptGenRandom(hCryptProv, chunk, buffer))
{
...
}
...
return 0;
}
CryptGenRandom()
is declared in thewincrypt.h
file and defined in theAdvapi32.lib
andAdvapi32.dll
libraries(These files are provided by Microsoft)
关于python - random.random() 在 python 中究竟是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41998399/
Feel free to skip straight to TL/DR if you're not interested in details of the question 简短的序言: 我最近决定
我一直在阅读 A Tour of Go学习Go-Lang到目前为止一切顺利。 我目前在 Struct Fields类(class),这是右侧的示例代码: package main import "fm
Last time I got confused顺便说一下PowerShell急切地展开集合,基思总结了它的启发式如下: Putting the results (an array) within a
我是一名优秀的程序员,十分优秀!