CodeQL 文档

当操作数支持 __eq__ 时,使用 is 比较运算符

ID: py/comparison-using-is
Kind: problem
Security severity: 
Severity: warning
Precision: high
Tags:
   - reliability
   - correctness
Query suites:
   - python-security-and-quality.qls

点击查看 CodeQL 代码库中的查询

当使用 isis not 运算符比较两个值时,测试的是两个值的**对象标识**而不是它们的相等性。如果比较中的任何一个值的类重新定义了相等性,那么即使对象比较为相等,is 运算符也可能返回 False。相等性由 __eq__ 方法定义,或者在 Python 2 中由 __cmp__ 方法定义。要比较两个对象的相等性,请使用 ==!= 运算符。

建议

当你想要比较两个字面量的值时,请使用比较运算符 ==!= 来代替 isis not

如果唯一性属性或性能很重要,那么请使用一个不重新定义相等性的对象。

示例

在以下示例的第一行中,程序员使用 is 运算符测试 value 的值与 DEFAULT 的值。不幸的是,当函数使用字符串 "default" 调用时,这可能会失败。

为了正常工作,请将表达式 value is DEFAULT 更改为 value == DEFAULT。或者,如果需要唯一性属性,请将 DEFAULT 的定义更改为以下任一备选方案。


DEFAULT = "default"

def get_color(name, fallback):
    if name in COLORS:
        return COLORS[name]
    elif fallback is DEFAULT:
        return DEFAULT_COLOR
    else:
        return fallback

#This works
print (get_color("spam", "def" + "ault"))

#But this does not
print (get_color("spam", "default-spam"[:7]))

#To fix the above code change to object
DEFAULT = object()

#Or if you want better repr() output:
class Default(object):

    def __repr__(self):
        return "DEFAULT"

DEFAULT = Default()

参考

  • Python 标准库:比较

  • ©GitHub, Inc.
  • 条款
  • 隐私