pylint:Class' message'没有' startwith'会员

时间:2017-02-01 15:18:43

标签: python python-2.7 pylint

出于某种原因,pylint 1.6.4(astroid 1.4.9)不喜欢这样:

===

它抱怨道:

try:
    some_package.their_function()
except Exception as ex:
    if ex.message.startswith(...):
        ...

我觉得这很令人惊讶,因为:

error (E1101, no-member, feed_sentiment) Class 'message' has no 'startswith' member

我认为这是bug in pylint

但是,做错了什么?什么是" pythonic"这里的方式?

PS。是的,我知道正确的方法是定义我自己的异常子类,但我无法控制>>> type(Exception("foo").message) <type 'str'> >>> Exception("foo").message.startswith <built-in method startswith of str object at 0x10520d360>

PPS。是的,我知道我可以使用some_package注释代码。

2 个答案:

答案 0 :(得分:1)

这确实是astroid中的一个错误 - 一个pylint的内部库,用于构建抽象语法树和值推理。

import astroid

node = astroid.builder.parse("""
    ex = Exception()
    msg = ex.message
""")
print list(node.locals['msg'][0].infer())

此代码段的输出为:

[<ClassDef(message) l.0 [exceptions] at 0x34aadd0>, <ClassDef(message) l.0 [exceptions] at 0x3482cb0>]

输出意味着异常实例上的message属性被推断为自定义类定义,而不是字符串实例。

感谢您提交错误!

答案 1 :(得分:0)

pythonic方法是明确地将ex转换为str,因为它还会将消息转换为字符串:

try:
    some_package.their_function()
except Exception as ex:
    if str(ex).startswith(...):  # or "if something in str(ex)":

Exception.message的问题在于它可能不是str

>>> try:
...     raise ValueError(1.2)
... except Exception as ex:
...     print ex
...     print type(ex.message)
...     print repr(str(ex))  # force it to be a string
...     print hasattr(ex.message, 'startswith')
ValueError(1.2,)
<type 'float'>
'1.2'
False

使用str作为消息,这是一种很好的风格和强烈建议,但这绝不是保证!