在不引发PEP8错误的情况下表达IS NOT NULL

23 投票
2 回答
6754 浏览
提问于 2025-04-18 08:14

在我的项目中,有一个时候我需要查询一个SQLAlchemy对象,找出那些不为空的列。在我的代码中,我这样写:

session.query(MyModel).filter(MyModel.my_column != None).all()

...这样运行得很好。不过,每当我用pep8或者其他代码检查工具检查这个文件时,它会报错E711:比较None时应该用if cond is not None:。我同意这个规则的意思,所以我不想因为一小行代码就忽略这个警告。

有没有其他写法呢?最好是那种不需要深入func模块的方式?

2 个回答

0

另外,你还可以通过使用对 None 的引用来绕过验证,而不是直接使用 None 本身:

NULL = None

def query_stuff():
    ...
    session.query(MyModel).filter(MyModel.my_column != NULL).all()
38

PEP8并不是说你必须严格遵守。

推荐你用 is None 而不是 == None,因为 is 这个操作符是不能被重载的(和 == 不一样):

>>> class Bad(object):
...     def __eq__(self, other):
...         return True
...
>>> instance = Bad()
>>> instance == None
True
>>> instance is None
False

在你的情况下,你其实是想用重载的 == 操作符,所以这个警告是不正确的。

有三种方法可以消除这个警告:

  1. 你可以只针对这一行禁用这个特定的警告:

    • 对于 Flake8/PyFlakes:

      session.query(MyModel).filter(MyModel.my_column != None).all()  # noqa: E711
      
    • 对于 Pylint:

      session.query(MyModel).filter(MyModel.my_column != None).all()  # pylint: disable=singleton-comparison
      
  2. 你可以直接调用类的 __eq__(对应 ==)和 __ne__(对应 !=)方法,而不使用相等操作符:

    session.query(MyModel).filter(MyModel.my_column.__ne__(None)).all()
    
  3. 你可以使用 .is_.isnot

    session.query(MyModel).filter(MyModel.my_column.isnot(None)).all()
    

    注意 .is_.isnot== 以及 != 是不一样的。MyModel.my_column != x 可能表示 IS NOT NULL 或者 != x,这取决于 x 的值和你的数据库,所以如果你真的不喜欢使用 __ 方法,并且知道表达式右边的类型,方案1和方案2可能更好。

撰写回答