为什么我无法在 Python 中扩展 bool?

发布于 2024-08-19 18:21:12 字数 311 浏览 3 评论 0 原文

>>> 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 信任程序员。

>>> 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

I thought Python trusted the programmer.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

往日情怀 2024-08-26 18:21:12

Guido 对此的看法:

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

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

Guido's take on it:

I thought about this last
night, and realized that you shouldn't
be allowed to subclass bool at all! A
subclass would only be useful when it
has instances, but the mere existance
of an instance of a subclass of bool
would break the invariant that True
and False are the only instances of
bool! (An instance of a subclass of C
is also an instance of C.) I think
it's important not to provide a
backdoor to create additional bool
instances, so I think bool should not
be subclassable.

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

吲‖鸣 2024-08-26 18:21:12

由于OP在评论中提到:

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

我认为重要的是要指出这是完全不可能的:Python 不允许您改变内置类型(特别是它们的特殊方法)。文字 1 始终是内置类型 int 的实例,并且在任何情况下 and 运算符的基本语义都不可重写-- a 和 b 始终b if a else a 对于任何 a 相同code> 和 b (不涉及 bool 强制,即使 OP 似乎错误地认为正在发生)。

重申这一关键点:a 和 b 的值始终、不变ab —— 这里是 没有 打破这种语义约束的方法(即使 ab 是您自己的特殊类的实例 - 当然,当它们被限制为 Python 内置 int 的实例!-)。

Since the OP mentions in a comment:

I want 1 and 2 to return an instance
of my class.

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 type int, and in any case the basic semantics of the and operator are not overridable anyway -- a and b is always identical to b if a else a for any a and b (no bool 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 either a or b -- there is no way to break this semantic constraint (even if a and b were instances of your own peculiar classes -- even less so of course when they're constrained to be instances of Python's built-in int!-).

长不大的小祸害 2024-08-26 18:21:12

如果您使用的是 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).

¢好甜 2024-08-26 18:21:12

这里有一篇文章解释了该决定背后的原因: 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 be True or to be False, and adding to that would only serve to complicate your code elsewhere.

渡你暖光 2024-08-26 18:21:12

因为 bool 应该只有两个值 - TrueFalse。如果您能够子类化 bool,您就可以为它定义任意数量的值,而这绝对不是您想要发生的情况。

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

Because bool is supposed to only have two values -- True and False. If you were able to subclass bool, 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?

木格 2024-08-26 18:21:12

我认为没有特别好的理由来禁止子类化 bool

Guido 说(正如投票最高、接受的答案中所引用的),它保留了 TrueFalsebool 唯一实例的不变式。 。但事实并非如此:

>>> class BOOL:
...     @property
...     def __class__(self):
...         return bool
...
>>> FileNotFound = BOOL()
>>> isinstance(FileNotFound, bool)
True
>>>

__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 and False are the only instances of bool. But that is not true:

>>> class BOOL:
...     @property
...     def __class__(self):
...         return bool
...
>>> FileNotFound = BOOL()
>>> isinstance(FileNotFound, bool)
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 that isinstance(x, bool) is a safe equivalent of x 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, not isinstance(x, T), in any case. Making those expressions equivalent in the one case of bool—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) is BOOL, not bool, so the exact-type test does work here. A malicious actor could, I suppose, replace type. Generally, expecting any sort of invariant to hold in Python is a fool's errand.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文