在现代Python中声明自定义异常类的正确方法是什么?我的主要目标是遵循标准的其他异常类,因此(例如)我在异常中包含的任何额外字符串都会被捕获异常的任何工具打印出来.
通过"现代Python",我指的是将在Python 2.5中运行的东西,但对于Python 2.6和Python 3*的处理方式来说是"正确的".而"自定义"我指的是一个Exception对象,它可以包含有关错误原因的额外数据:一个字符串,也许还有一些与异常相关的任意对象.
我被Python 2.6.2中的以下弃用警告绊倒了:
>>> class MyError(Exception):
... def __init__(self, message):
... self.message = message
...
>>> MyError("foo")
_sandbox.py:3: DeprecationWarning: BaseException.message has been deprecated as of Python 2.6
Run Code Online (Sandbox Code Playgroud)
看起来很疯狂,BaseException对于名为的属性具有特殊含义message.我从PEP-352收集到该属性确实在2.5中有特殊含义他们试图弃用,所以我猜这个名字(而且仅此一个)现在被禁止了?啊.
我也模糊地意识到它Exception有一些神奇的参数args,但我从来不知道如何使用它.我也不确定这是向前发展的正确方法; 我在网上发现的很多讨论都表明他们试图在Python 3中废除args.
更新:两个答案建议覆盖__init__,和__str__/ __unicode__/ __repr__.这似乎很多打字,是否有必要?
编辑:我正在运行python 2.6
我希望实现这样的目标:
def foo():
try:
raise IOError('Stuff ')
except:
raise
def bar(arg1):
try:
foo()
except Exception as e:
e.message = e.message + 'happens at %s' % arg1
raise
bar('arg1')
Run Code Online (Sandbox Code Playgroud)
Traceback...
IOError('Stuff Happens at arg1')
Run Code Online (Sandbox Code Playgroud)
但我得到的是:
Traceback..
IOError('Stuff')
Run Code Online (Sandbox Code Playgroud)
关于如何实现这一点的任何线索?
从Python中的标准库组件中获取异常消息的最佳方法是什么?
我注意到在某些情况下你可以通过message字段得到它:
try:
pass
except Exception as ex:
print(ex.message)
Run Code Online (Sandbox Code Playgroud)
但在某些情况下(例如,在套接字错误的情况下)你必须做这样的事情:
try:
pass
except socket.error as ex:
print(ex)
Run Code Online (Sandbox Code Playgroud)
我想知道是否有任何标准方法可以涵盖大部分情况?
在python 2.6.6中,我如何捕获异常的错误消息.
IE:
response_dict = {} # contains info to response under a django view.
try:
plan.save()
response_dict.update({'plan_id': plan.id})
except IntegrityError, e: #contains my own custom exception raising with custom messages.
response_dict.update({'error': e})
return HttpResponse(json.dumps(response_dict), mimetype="application/json")
Run Code Online (Sandbox Code Playgroud)
这似乎不起作用.我明白了:
IntegrityError('Conflicts are not allowed.',) is not JSON serializable
Run Code Online (Sandbox Code Playgroud) 我试图在Python 2.6中定义我自己的(非常简单的)异常类,但无论我怎么做,我都会收到一些警告.
首先,最简单的方法:
class MyException(Exception):
pass
Run Code Online (Sandbox Code Playgroud)
这有效,但在运行时打印出警告:DeprecationWarning:BaseException.message自Python 2.6起已被弃用,所以不是这样.然后我尝试了:
class MyException(Exception):
def __init__(self, message):
self.message = message
Run Code Online (Sandbox Code Playgroud)
这也有效,但PyLint报告了一个警告:W0231: MyException.__init__: __init__ method from base class 'Exception' is not called.所以我试着说:
class MyException(Exception):
def __init__(self, message):
super(Exception, self).__init__(message)
self.message = message
Run Code Online (Sandbox Code Playgroud)
这也有效!但现在PyLint报告错误:E1003: MyException.__init__: Bad first argument 'Exception' given to super class
我该怎么做这么简单的事情没有任何警告?
我想我的Python unittest模块告诉测试运行器在某些情况下跳过它的全部(例如无法导入模块或找到关键资源).
我可以使用@unittest.skipIf(...)跳过unittest.TestCase类,但是如何跳过整个模块?将跳过应用于每个类是不够的,因为如果模块无法导入,类定义本身可能会导致异常.
except ImportError as xcpt:
print "Import Error: " + xcpt.message
Run Code Online (Sandbox Code Playgroud)
在2.6中获取弃用警告,因为消息正在消失. 堆栈溢出
你应该如何处理ImportError?(注意,这是一个内置的例外,不是我的一个......)
为什么这不起作用?
try:
1/0
except ZeroDivisionError as e:
e.message += ', you fool!'
raise
Run Code Online (Sandbox Code Playgroud)
即使它仍在异常实例上,也不会使用修改后的消息.上面有一个工作模式吗?行为应该像我目前的解决方法如下:
try:
1/0
except ZeroDivisionError as e:
args = e.args
if not args:
arg0 = ''
else:
arg0 = args[0]
arg0 += ', you fool!'
e.args = (arg0,) + args[1:]
raise
Run Code Online (Sandbox Code Playgroud)
我知道python3中的异常链接,它看起来不错但很遗憾在python2中不起作用.那么在python2中重新引发异常的常用方法是什么?
注意:由于此处提到的警告和警告,我不想挖掘回溯并创建新的异常,而是重新引发现有的异常实例.