【问题标题】:Is it a good idea to define my own random.randbool?定义我自己的 random.randbool 是个好主意吗?
【发布时间】:2016-02-28 12:44:57
【问题描述】:

Python 没有random.randbool 函数,尽管它有randintrandrangerandom。如果我想使用randbool 函数,没有什么能阻止我使用以下代码:

import random
random.randbool = lambda: random.random() >= 0.5

是否建议这样做?它是“pythonic”吗?是不是慢很多?这绝对有助于在以后的代码中易于理解,因为内联 random.random() >= 0.5random.choice([False, True]) 可能会更令人困惑。

当然,另一种方法是使用常规函数 -

def randbool():
    return random.random() >= 0.5

哪个更好?

编辑:一些timeit 基准测试:

> python -m timeit -s "import random" -s "def randbool():" -s " return random.random() >= 0.5" "randbool()
1000000 loops, best of 3: 0.275 usec per loop

> python -m timeit -s "import random" "random.random() >= 0.5"
10000000 loops, best of 3: 0.152 usec per loop

> python -m timeit -s "import random" -s "random.randbool = lambda: random.random() >= 0.5" "random.randbool()"
1000000 loops, best of 3: 0.322 usec per loop

> python -m timeit -s "import random" "random.choice([False, True])"
100000 loops, best of 3: 2.03 usec per loop

> python -m timeit -s "import random" "random.randint(0, 1)"
100000 loops, best of 3: 2.9 usec per loop

所以,最快的是内联,然后是常规函数,然后定义random.randboolchoicerandint 慢得多。

【问题讨论】:

  • IMO random.choice([False, True]) 非常优雅且不言自明。回覆。 speed:你为什么不测试一下?
  • 另请注意,几乎没有任何情况下您不能使用整数 0 和 1 来代替 False 和 True,所以 randint 就可以了。
  • IMO 我永远不会在实际代码中像这样从外部修改库。在实用程序文件或其他地方定义它,但不要将其添加到random
  • 只是想连接到this answer,这也暗示了random.getrandbits(1)
  • 这个问题非常基于意见,并提出了几个不同的问题,但很可能可以编辑成更好的形式。

标签: python


【解决方案1】:

这有点基于意见,但我会尽量支持我的意见。

修补标准库模块通常被认为是不好的形式 - 内置甚至禁止猴子修补。我不这样做的主要原因是为了保持一致性。如果其他人看到了您的代码(或者您稍后返回),那么您可能想查看的任何地方都没有 random.randbool 的文档或规范。这是误导性的,这与 python 的“显式胜于隐式”的口头禅背道而驰。

相反,我建议选择最快的方法 (random.random() < .5) 并从中创建一个辅助函数。由于性能似乎是一个问题,以下是我的机器给出的一些相关示例:

In [30]: %timeit randbool()
10000000 loops, best of 3: 184 ns per loop

In [31]: %timeit random.random() < .5
10000000 loops, best of 3: 114 ns per loop

In [32]: %timeit random.randint(0,1)
1000000 loops, best of 3: 1.18 µs per loop

如果你想用你的辅助函数打字,你会得到什么:

In [33]: %timeit bool(randbool())
1000000 loops, best of 3: 310 ns per loop

总而言之,仍然相当快,即使有函数调用的开销(无论如何你都会从修补random 中获得)。

【讨论】:

    【解决方案2】:

    Ruby 中很常见的是实现 mixins,它可以增强 标准库 中类的可用方法。很多 Rails 的东西都是这样构建的。

    但我没有看到任何迹象表明这是 Python 中的良好做法。如果标准模块缺少某些功能,创建自己的模块是很常见的。这样做的好处是,您不会给其他任何可能查看您的代码的人留下一些功能/方法来自标准集的印象。我认为大多数 Python 达人 信任他们在模块开头看到的导入。

    如果您的方法较慢,我无法回答。过去,我不得不使用元编程“patch”原始 Python 库,但这样做是为了确保我们为测试方法提供一致的接口。

    【讨论】:

      【解决方案3】:

      你回答了你的问题:

      不管是什么

      1. 更容易阅读
      2. 执行速度更快
      3. 写得更短

      更好。这是我的优先级,以您认为合适并适合您需求的方式重新排列它们。

      【讨论】:

      • 没有一个选项是最容易阅读、最快执行和最短编写的。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多