为什么我无法在 Python 中扩展 bool?
>>> 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 信任程序员。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
Guido 对此的看法:
参考: http://mail.python.org/pipermail/python -dev/2002-March/020822.html
Guido's take on it:
Reference: http://mail.python.org/pipermail/python-dev/2002-March/020822.html
由于OP在评论中提到:
我认为重要的是要指出这是完全不可能的:Python 不允许您改变内置类型(特别是它们的特殊方法)。文字
1
始终是内置类型int
的实例,并且在任何情况下and
运算符的基本语义都不可重写--a 和 b
始终 与b if a else a
对于任何a
相同code> 和b
(不涉及bool
强制,即使 OP 似乎错误地认为正在发生)。重申这一关键点:
a 和 b
的值始终、不变为a
或b
—— 这里是 没有 打破这种语义约束的方法(即使a
和b
是您自己的特殊类的实例 - 当然,当它们被限制为 Python 内置int
的实例!-)。Since the OP mentions in a comment:
I think it's important to point out that this is entirely impossible: Python does not let you alter built-in types (and, in particular, their special methods). Literal
1
will always be an instance of built-in typeint
, and in any case the basic semantics of theand
operator are not overridable anyway --a and b
is always identical tob if a else a
for anya
andb
(nobool
coercion involved, even though the OP appears to mistakenly believe one is happening).Restating this crucial point: the value of
a and b
is always, unchangeably eithera
orb
-- there is no way to break this semantic constraint (even ifa
andb
were instances of your own peculiar classes -- even less so of course when they're constrained to be instances of Python's built-inint
!-).如果您使用的是 Python 3,并且希望有一个可以作为布尔值计算的类,但也包含其他功能,请实现
__bool__
在你的班级中。在 Python 2 中,可以通过实现
来实现相同的效果__nonzero__
或__len__
(如果您的类是容器)。If you are using Python 3, and you want to have a class that can be evaluated as a boolean, but also contain other functionality, implement
__bool__
in your class.In Python 2 the same effect can be achieved by implementing
__nonzero__
or__len__
(if your class is a container).这里有一篇文章解释了该决定背后的原因: http:// /mail.python.org/pipermail/python-dev/2004-February/042537.html
这个想法是
bool
有一个特定的目的 - 是True
或为False
,添加它只会使其他地方的代码变得复杂。Here is a post that explains the reasoning behind the decision: http://mail.python.org/pipermail/python-dev/2004-February/042537.html
The idea is that
bool
has a specific purpose - to beTrue
or to beFalse
, and adding to that would only serve to complicate your code elsewhere.因为
bool
应该只有两个值 -True
和False
。如果您能够子类化bool
,您就可以为它定义任意数量的值,而这绝对不是您想要发生的情况。更好的问题是:为什么要扩展 bool?
Because
bool
is supposed to only have two values --True
andFalse
. If you were able to subclassbool
, you could define arbitrary numbers of values for it, and that's definitely not what you want to happen.A better question is: why do you want to extend bool?
我认为没有特别好的理由来禁止子类化
bool
。Guido 说(正如投票最高、接受的答案中所引用的),它保留了
True
和False
是bool
唯一实例的不变式。 。但事实并非如此:__class__
的这种行为是 已记录并在标准库中使用。我想你可能会争辩说,禁止子类化仍然保留了 bool 的某种“道德”封闭性,但我不清楚这有什么好处。阅读 Guido 的基本原理,一个理性的 Python 程序员会得出结论,他说的 isinstance(x, bool) 是一个安全等价于 x is True 或 x is False 的安全等价物,但事实并非如此。 t。
此外,如果确切的类型对您很重要,那么无论如何您都应该测试
type(x) is T
,而不是isinstance(x, T)
。使这些表达式在 bool 的一种情况下等效(即使他们成功地做到了这一点)只会鼓励在这种情况下编写不能清楚表达意图的代码。(
type(FileNotFound)
是BOOL
,而不是bool
,因此精确类型测试在这里确实有效。我想,恶意行为者可以,替换type
。一般来说,期望 Python 中保持任何类型的不变量都是愚蠢的。)I think there is no particularly good reason to prohibit subclassing
bool
.Guido said (as quoted in the top-voted, accepted answer) that it preserves the invariant that
True
andFalse
are the only instances ofbool
. But that is not true:This behavior of
__class__
is documented and used in the standard library.I guess you could argue that the prohibition on subclassing still preserves some kind of "moral" closedness of
bool
, but it's not clear to me what good that is. Reading Guido's rationale, a reasonable Python programmer would conclude he's saying thatisinstance(x, bool)
is a safe equivalent ofx is True or x is False
, which it isn't.Furthermore, if the exact type matters to you, you should be testing
type(x) is T
, notisinstance(x, T)
, in any case. Making those expressions equivalent in the one case ofbool
—even if they succeeded in doing it—would just encourage the writing of code that doesn't clearly express intent, in that one case.(
type(FileNotFound)
isBOOL
, notbool
, so the exact-type test does work here. A malicious actor could, I suppose, replacetype
. Generally, expecting any sort of invariant to hold in Python is a fool's errand.)