【问题标题】:Understanding the truthiness of strings理解字符串的真实性
【发布时间】:2018-08-07 21:01:45
【问题描述】:

我知道 Python 内置类型有一个“真实性”值,空字符串被认为是False,而任何非空字符串都被认为是True

这是有道理的

我可以使用内置函数bool 进行检查。

>>> bool("")
False

>>> bool("dog")
True

在使用条件句时,我也可以利用这些真实性值。例如:

>>> if "dog":
...     print("yes")
...
yes

这令人困惑

这不适用于 == 运算符:

>>> "dog" == True
False

>>> "dog" == False
False

谁能解释为什么== 的行为似乎与条件不同?

【问题讨论】:

  • 您阅读过文档吗?
  • == 是比较运算符。字符串和布尔值永远不能相等。
  • 比较"dog" == "True"时,您也在比较这些对象的类型,而不仅仅是它们的布尔值。
  • 这里比较的是类型,而不是值
  • 我有裤子。我不等于我的裤子。字符串具有真值。一个字符串不等于它的真值。

标签: python python-3.x boolean truthiness


【解决方案1】:

请参阅文档的truth value testingcomparisons 部分,摘录如下。

简而言之,大多数事情在默认情况下都是真实的,这就是为什么bool("dog") 是真实的。 == 运算符比较两个对象的相等性,而不是比较它们的真实性,正如我假设你所期望的那样。

4.1.真值测试

可以测试任何对象的真值,用于 if 或 while 条件或作为以下布尔运算的操作数。

默认情况下,一个对象被认为是真的,除非它的类定义 返回 False 的 __bool__() 方法或 __len__() 方法 使用对象调用时返回零。

以下是大多数被认为是错误的内置对象:

  • 常量定义为假:NoneFalse
  • 任何数字类型的零:00.00jDecimal(0)Fraction(0, 1)
  • 空序列和集合:''()[]{}set()range(0)

始终具有布尔结果的操作和内置函数 返回 0 或 False 表示假,1 或 True 表示真,除非另有说明 表示。 (重要的例外:布尔运算 orand 总是返回其中一个操作数。)

4.3.比较

不同类型的对象,除了不同的数字类型,从不 比较相等。

...

类的不同实例通常比较为不相等 除非该类定义了__eq__() 方法。

【讨论】:

    【解决方案2】:

    基础知识

    我相信你的困惑可能来自于将 Python 与诸如 JavaScript 之类的语言进行比较,其中有一个 == 和一个 === 运算符。 Python 不能以这种方式工作。

    在 Python 中,比较相等性的唯一方法是使用 ==,它会比较值和类型。

    因此,如果您比较 True == "dog",则表达式立即为 False,因为类型 boolstr 不是可以比较的类型。

    不过,请注意,这并不意味着它们之间没有可比较的类型。例如setfrozenset

    frozenset({1,2,3}) == {1,2,3} # True
    

    或者只是intfloat

    1 == 1.0 # True
    

    这是大多数内置类型的行为。

    经典部分

    在您定义自己的类型的情况下,即定义类时,您可以编写__eq__,当您将类对象与另一个值进行比较时会调用它。

    例如,您可以这样做(顺便说一句,在 cmets 中指出这是一个糟糕的想法,您不应该继承内置类型)。

    class WeirdString(str):
        def __eq__(self, other):
            return str(self) == str(other) or bool(self) == bool(other)
    
    s = WeirdString("dog")
    s == True # True
    

    如果您没有定义__eq__,那么Python 会退回到比较对象是否同一个对象is

    【讨论】:

    • 对于那些想知道我为什么说对于大多数内置类型的人来说,我在想像这样的阴暗的东西:docs.python.org/3/library/stdtypes.html#memoryview.__eq__
    • 明确地说,WeirdString 是一个可怕的想法。在这种情况下,s 将等于"foo"{1}[1]-200.5{'a': 1}object() 等。Python 被强类型化是有原因的;由于动态类型已经在发挥作用,弱类型几乎不可能编写您可以有效推理的代码。这里真正的教训是编写惯用的代码,从不使用== True== False,只使用隐含的真实性。
    • 这是一个糟糕的想法,我会提到这一点。
    • 另外,标准== 没有明确地测试类型。不同的数值类型是可比较的,set 可以和frozenset 进行比较,许多类似字节的类型按预期相互比较等等。不要在这里引入 JS 的 === 的显式类型检查,它只会混淆这件事。
    • 我修改了我的答案,包括你的评论,顺便说一句。
    【解决方案3】:

    当您比较 "dog" == True 时,您也在比较这些对象的类型,而不仅仅是它们的布尔值。

    现在True 的类型为bool"dog" 的类型为str,根据== 运算符,它们不等价,无论它们的布尔值是否相等。

    注意:这里检查对象的类型和布尔值。

    【讨论】:

    • True 在非布尔型双引号内
    • @bro-grammer,谢谢我修好了!
    猜你喜欢
    • 2012-04-08
    • 2017-08-20
    • 2011-10-02
    • 2012-10-21
    • 2019-05-29
    • 1970-01-01
    • 1970-01-01
    • 2018-09-17
    • 2014-03-24
    相关资源
    最近更新 更多