出于某种原因,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
注释代码。
答案 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
作为消息,这是一种很好的风格和强烈建议,但这绝不是保证!