【问题标题】:Edit boolean and operator编辑布尔值和运算符
【发布时间】:2018-06-05 02:50:47
【问题描述】:

所以我一直在使用类中的标准运算符来尝试看看我能做什么,但我无法找到如何编辑布尔 and 运算符。

我可以通过定义 __and__(self) 来编辑按位 &operator,但不能像 and 那样进行编辑。有谁知道我如何改变a and b 的行为,其中ab 是我正在制作的课程的实例?

提前致谢!

【问题讨论】:

  • 你不能,因为这不取决于操作数的类型,而是取决于thruthiness。

标签: python boolean operators


【解决方案1】:

在 Python 2 中,andor 访问 __nonzero__

>>> class Test(object):
...     def __nonzero__(self):
...         print '__nonzero__ called'
...         return True
... 
>>> Test() and 1
__nonzero__ called
1

在 Python 3 中,__nonzero__ 已重命名为 __bool__

>>> class Test:
...     def __bool__(self):
...         print('__bool__ called')
...         return True
... 
>>> Test() and 1
__bool__ called
1

请注意,短路评估可能会抑制对__nonzero____bool__ 的调用。

>>> 0 and Test()
0
>>> 1 or Test()
1

另一个需要注意的特点是,如果__nonzero__ / __bool__ 未定义,Python 会尝试访问__len__,如果__len__ 返回的值不是0,则将对象视为真实对象。如果两个方法都定义了,__nonzero__ / __bool__ 获胜。

>>> class Test:
...     def __len__(self):
...         return 23
... 
>>> Test() and True
True
>>>
>>> class Test:
...     def __len__(self):
...         return 23
...     def __bool__(self):
...         return False
... 
>>> Test() and True
<__main__.Test object at 0x7fc18b5e26d8> # evaluation stops at Test() because the object is falsy
>>> bool(Test())
False

有没有什么办法可以让这个返回一个布尔值以外的东西,比如一个布尔值列表?

很遗憾,没有。 documentation 声明该方法应该返回 FalseTrue,但实际上如果你让它返回其他东西,你会得到一个 TypeError

>>> class Test:
...     def __bool__(self):
...         return 1
... 
>>> Test() and 42
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __bool__ should return bool, returned int
>>> 
>>> bool(Test())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: __bool__ should return bool, returned int

【讨论】:

  • 有什么办法可以让我返回一个布尔值以外的东西,比如一个布尔值列表?
【解决方案2】:

and 运算符使用__bool__ 将第一个操作数转换为布尔值,然后对布尔值执行预定义的操作(如果first.__bool__()True,则返回第二个,否则首先返回)。没有办法改变这种行为。

【讨论】:

  • 其实b.__bool__() 永远不会被调用,我的回答有点不准确。
  • @pycoder 你实际上说的是 "如果first.__bool__()True,则返回第二个" 但在这种情况下返回的是第二个的布尔值;不是第二个本身。
  • @ev 1 and "asdf" == "asdf"
猜你喜欢
  • 2014-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-27
  • 2011-03-27
相关资源
最近更新 更多