![](/img/trans.png)
[英]Python Exception Handling - exception raised with a string message, excepted as list of characters
[英]Python decorated exception cant be excepted
我使用了一个装饰器类来装饰一个Exception,但是,似乎异常似乎无法使用确切的异常类进行例外处理。 使用functools.update_wrapper更新装饰器类也不起作用。
class ClsDecor(object):
def __init__(self,cls):
self.cls=cls
self.counter=0
def __call__(self,*args):
self.counter+=1
return self.cls(*args)
@ClsDecor
class Err(Exception):
def __init__(self):
Exception.__init__(self)
try:
raise Err()
except Err as e:
print 'catched'
except Exception as e:
print 'Not catched'
首先,方法__call__
应该是:
def __call__(self, *args):
return self.cls(*args)
你的代码会在__call__
引发一个错误并直接print 'Not catched'
,这是第一级错误。 修复此错误后,您将达到类型不匹配的第二级错误,这在dhke的评论中得到了很好的解释。 基本想法是Err
实际上是输入ClsDecor
后@ClsDecor
,但是你回到原始类型的实例Err
在__call__
,这是明显的与不匹配except Err
。 您可以轻松使用装饰器来存档您的目的,如:
def err_dec(Cls):
class NewErr(Exception):
def __init__(self, *args, **kwargs):
self.err = Cls(*args, **kwargs)
return NewErr
@err_dec
class Err(Exception):
def __init__(self):
Exception.__init__(self)
更新了评论中的要求:
def err_dec(Cls):
class NewErr(Exception):
c = 0
def __init__(self, *args, **kwargs):
NewErr.c = NewErr.c + 1
self.err = Cls(*args, **kwargs)
def counter(self):
return NewErr.c
return NewErr
@err_dec
class Err(Exception):
def __init__(self):
Exception.__init__(self)
try:
Err()
Err()
raise Err()
except Err as e:
print e.counter()
print 'catched'
except Exception as e:
print 'Not catched'
问题不在于装饰。 也许装饰让你困惑,但那不是问题。
你需要意识到Err
是什么。 Decorator的工作方式与普通定义类似,但在分配名称之前将装饰器应用于对象。 这相当于:
class Err(Exception):
def __init__(self):
Exception.__init__(self)
Err = ClsDecor(Err)
现在Err
是一个ClsDecor
实例,在提升它时你正在调用实例(而不是类),你将调用ClsDecor.__call__
(而不是ClsDecor.__init__
)。 当你尝试用参数( args
)调用self.cls
时就会发生Err
,但是self.cls
是Err
,它不带任何额外的参数(除了self
)。
如果你在default except
子句中打印了错误,你会看到这个。 如果你点击默认子句,打印错误是个好主意,因为它常常是因为你遇到了一个意外的异常:
except Exception as e:
print 'Not catched', repr(e)
raise
或许你根本不应该抓住它 - 如果没有抓住异常,那么无论如何都会打印回溯。
随着所有人的帮助,我终于得到了这样的解决方案:
class ErrMetaClass(type):
def __new__(mcls,cls_name,cls_parents,cls_attr):
return super(ErrMetaClass,mcls).__new__(mcls,
cls_attr['_cls'].__name__, cls_parents,cls_attr)
def err_dec(cls):
class NewErr(Exception):
__metaclass__ = ErrMetaClass
_cls=cls
c=0
def __init__(self):
NewErr.c+=1
return NewErr
@err_dec
class Err(Exception):
def __init__(self):
Exception.__init__(self)
try:
raise Err()
except Err as e:
print Err.c
except Exception as e:
print type(e)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.