【问题标题】:Why I can't extend bool in Python?为什么我不能在 Python 中扩展 bool?
【发布时间】:2011-01-11 10:42:52
【问题描述】:
>>> class BOOL(bool):
...     print "why?"
... 
why?
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Error when calling the metaclass bases
    type 'bool' is not an acceptable base type

我认为 Python 信任程序员。

【问题讨论】:

  • 是否要添加 FileNotFound 值?
  • Google 搜索或 SO 搜索“组合与继承”可能在这里有用。

标签: python boolean restriction


【解决方案1】:

如果您使用的是 Python 3,并且您希望有一个可以作为布尔值评估但还包含其他功能的类,请在您的类中实现 __bool__

在 Python 2 中,可以通过实现 __nonzero____len__(如果您的类是容器)来实现相同的效果。

【讨论】:

  • 在 Python 2.x 中,您可以通过实现 __nonzero____len__ 来做同样的事情。
  • 我希望 1 和 2 返回我的类的一个实例。你会怎么做?
  • 第一个子类化 bool,然后覆盖 int 方法...为什么不从头开始创建自己的类?
【解决方案2】:

由于 OP 在评论中提到:

我希望1 and 2 返回一个实例 我班的。

我认为重要的是要指出这是完全不可能的:Python 不允许您更改 内置类型(尤其是它们的特殊方法)。文字 1 将始终是内置类型 int 的实例,并且在任何情况下,and 运算符的基本语义无论如何都不能被覆盖——a and b 总是相同b if a else a for any ab (不涉及 bool 强制,即使 OP 似乎错误地认为正在发生)。

重申这个关键点:a and b 的值是永远不变ab - 没有没有 方法可以打破这种语义约束(即使 ab 是您自己的特殊类的实例——当然,当它们被限制为 Python 的内置 int 的实例时更是如此!-)。

【讨论】:

【解决方案3】:

这里有一篇文章解释了这个决定背后的原因:http://mail.python.org/pipermail/python-dev/2004-February/042537.html

这个想法是 bool 有一个特定的目的 - 成为 True 或成为 False,添加它只会使您的代码在其他地方复杂化。

【讨论】:

    【解决方案4】:

    Guido 对此的看法:

    我最后想到了这个 晚上,并意识到你不应该 完全可以继承 bool !一种 子类只有在它有用时才有用 有实例,但仅仅是存在 bool 子类的实例 会打破 True 的不变量 和 False 是唯一的实例 布尔! (C 的子类的一个实例 也是 C 的一个实例。)我认为 重要的是不要提供 后门创建额外的布尔 实例,所以我认为 bool 不应该 可以子类化。

    参考:http://mail.python.org/pipermail/python-dev/2002-March/020822.html

    【讨论】:

    • True 和 False 是单例的。这是一个更好的答案。
    • 很高兴知道事情是一致的:class Foo(None.__class__): ... -> TypeError: type 'NoneType' is not an acceptable base type
    • 试图理解这个答案:从bool 继承不会以任何方式影响TrueFalse 的不变性。子类的一个实例仍然是TrueFalse(从bool 的角度来看)。如果您覆盖__eq__(),它可能具有其他属性,并且可能等于或不等于其中之一,否则它不会对bool或其两个可能值产生负面影响。我错过了什么?
    • @user3204459 在测试TrueFalseNone 之类的值时,我们可以使用标识操作is,因为我们知道这些值是单例的。许多代码已经依赖于这个技巧,因此对这些类型进行子类化会破坏这些基于身份的检查。
    • @flakes 抱歉,我还是不明白。 TrueFalse 仍将是 bool,并且只会在使用 is 时针对 TrueFalse 进行测试。所以呢?什么被打破了?你能举个具体的例子吗?为什么False 是单例的,而0 不是?
    【解决方案5】:

    因为bool 应该只有两个值——TrueFalse。如果你能够继承bool,你可以为它定义任意数量的值,这绝对不是你想要的。

    一个更好的问题是:为什么要扩展 bool?

    【讨论】:

    • 我想添加一个属性,让我可以跟踪对象上的一些东西。
    • @Juanjo 那么你想要的不是布尔值,它是一个布尔值和其他东西的元组。布尔值必须是 True 或 False,没有其他值和其他属性会使该类的实例与 True 和 False 进行否定比较。这将发生,它不再是布尔值。
    • 好的,但是我不能覆盖 int.__nonzero__ 来返回这个元组。我可以吗?
    • 答案:模糊逻辑、bool中的运算符重载等
    • 重载魔法方法并添加额外的方法,同时保持布尔运算的一致性。即,使用几个 mixin 来获得一个布尔类,该类可以很容易地转换为 ctypes 和字符串转换为/从字符串,其方式符合 C 自定义网络协议 API。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-09-16
    • 2011-12-09
    • 2015-11-17
    • 1970-01-01
    • 1970-01-01
    • 2013-03-30
    • 2010-12-10
    相关资源
    最近更新 更多