为啥我不能在 Python 中扩展 bool?
Posted
技术标签:
【中文标题】为啥我不能在 Python 中扩展 bool?【英文标题】: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 搜索“组合与继承”可能在这里有用。 【参考方案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 a
和 b
(不涉及 bool
强制,即使 OP 似乎错误地认为正在发生)。
重申这个关键点:a and b
的值是永远不变a
或b
- 没有没有 方法可以打破这种语义约束(即使 a
和 b
是您自己的特殊类的实例——当然,当它们被限制为 Python 的内置 int
的实例时更是如此!-)。
【讨论】:
不可能改变内置类型?这不是forbiddenfruit library 所做的吗?【参考方案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
继承不会以任何方式影响True
和False
的不变性。子类的一个实例仍然是True
或False
(从bool
的角度来看)。如果您覆盖__eq__()
,它可能具有其他属性,并且可能等于或不等于其中之一,否则它不会对bool
或其两个可能值产生负面影响。我错过了什么?
@user3204459 在测试True
、False
或None
之类的值时,我们可以使用标识操作is
,因为我们知道这些值是单例的。许多代码已经依赖于这个技巧,因此对这些类型进行子类化会破坏这些基于身份的检查。
@flakes 抱歉,我还是不明白。 True
和 False
仍将是 bool
,并且只会在使用 is
时针对 True
和 False
进行测试。所以呢?什么被打破了?你能举个具体的例子吗?为什么False
是单例的,而0
不是?【参考方案5】:
因为bool
应该只有两个值——True
和False
。如果你能够继承bool
,你可以为它定义任意数量的值,这绝对不是你想要的。
一个更好的问题是:为什么要扩展 bool?
【讨论】:
我想添加一个属性,让我可以跟踪对象上的一些东西。 @Juanjo 那么你想要的不是布尔值,它是一个布尔值和其他东西的元组。布尔值必须是 True 或 False,没有其他值和其他属性会使该类的实例与 True 和 False 进行否定比较。这将发生,它不再是布尔值。 好的,但是我不能覆盖 int.__nonzero__ 来返回这个元组。我可以吗? 答案:模糊逻辑、bool中的运算符重载等 重载魔法方法并添加额外的方法,同时保持布尔运算的一致性。即,使用几个 mixin 来获得一个布尔类,该类可以很容易地转换为 ctypes 和字符串转换为/从字符串,其方式符合 C 自定义网络协议 API。以上是关于为啥我不能在 Python 中扩展 bool?的主要内容,如果未能解决你的问题,请参考以下文章
为啥我不能直接将 int 或 bool 传递给 OCMock 的“andReturnValue”参数?
python3在pycharm中为啥导入random模块不能用? TypeError: 'module' object is not callable