在以下代码段中:
try:
raise Bob()
except Fred:
print "blah"
如何实施Bob和Fred的比较?
从玩起来似乎是在下面调用isinstance,这是正确的吗?
我问,因为我试图颠覆这个过程,特别是我希望能够构造一个Bob,使得它被execpt Fred捕获,即使它实际上不是Fred的实例或其任何子类
有几个人问我为什么要这样做......
我们有一个RMI系统,它是围绕使其尽可能无缝的理念而构建的,这是一个使用它的快速示例,请注意RMI系统中没有特定于套接字的代码,套接字只是提供了方便示例
import remobj
socket = remobj.RemObj("remote_server_name").getImport("socket")
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(("", 0))
print "listening on port:", s.getsockname()[1]
s.settimeout(10)
try:
print "received:", s.recv(2048)
except socket.timeout:
print "timeout"
现在在这个特定的例子中,except不能按预期工作,因为raise对象不是socket.timeout的实例,它是我们的一个代理助手类的实例。
答案 0 :(得分:6)
我相信您的猜测在比较的工作方式上是正确的,并且拦截的唯一方法是将Fred添加为Bob的基类。例如:
# Assume both Bob and Fred are derived from Exception
>>> class Bob(Bob, Fred):
... pass
...
>>> try:
... raise Bob()
... except Fred:
... print 'blah'
blah
据我所知,这是让它在你写的时候工作的唯一方法。但是,如果您只是将except:行重写为
... except (Bob, Fred):
它可以捕获Bob和Fred,而无需修改Bob的定义。
答案 1 :(得分:1)
我希望能够构建一个Bob 这样它就被execpt抓住了 弗雷德即使它实际上不是 弗雷德或其任何一个的例子 子类。
好吧,你可以抓住'Exception' - 但这不是非常pythonic。您应该尝试捕获正确的异常,然后作为最后的手段回退到一般的异常(所有异常都是子类)。如果这对您不起作用,那么在您的设计阶段就会出现严重错误。
See this note from Code Like A Pythonista
注意:始终指定例外 抓住。切勿使用裸露的条款。 除了条款外,裸露的东西都会被捕获 意想不到的异常,让你的 代码非常难以调试。
然而,Python的Zen中的一个成语是
特殊情况不足以打破规则。 虽然实用性胜过纯洁。
答案 2 :(得分:1)
>>> class Fred(Exception):
pass
>>> class Bob(Fred):
pass
>>> issubclass(Bob, Fred)
True
>>> issubclass(Fred, Bob)
False
>>> try:
raise Bob()
except Fred:
print("blah")
blah
所以基本上抓住了异常,因为Bob是Fred的子类,我假设,他们必须实现类似于issubclass(Bob, Fred)
的逻辑
看,这是你想要实现的方式,你想要的watever。当然不是在 init 中,而是在其他一些方法中。
>>> class Bob(Exception):
def __init__(self):
raise Fred
>>> try:
b = Bob()
except Fred:
print('blah')
blah
答案 3 :(得分:1)
我不清楚如何将socket.timeout中的异常隐藏到“无缝”理念中?捕获预期异常有什么问题?
try:
print "received:", s.recv(2048)
except socket.timeout:
print "timeout"
except our_proxy_helper_class:
print 'crap!'
或者,如果你真的想把它作为socket.timeout捕获,为什么不在just_proxy_helper_class中引发socket.timeout?
raise socket.timeout('Method x timeout')
因此,当你在our_proxy_helper_class中引发socket.timeout时,它应该被'除了socket.timeout'所捕获。
答案 4 :(得分:0)
至少在Python中,看起来有一个类型为10的COMPARE_OP操作(异常匹配)。你不可能做任何事情来破解这个计算。
>>> import dis >>> def foo(): ... try: ... raise OSError() ... except Exception, e: ... pass ... >>> dis.dis(foo) 2 0 SETUP_EXCEPT 13 (to 16) 3 3 LOAD_GLOBAL 0 (OSError) 6 CALL_FUNCTION 0 9 RAISE_VARARGS 1 12 POP_BLOCK 13 JUMP_FORWARD 21 (to 37) 4 >> 16 DUP_TOP 17 LOAD_GLOBAL 1 (Exception) 20 COMPARE_OP 10 (exception match) 23 JUMP_IF_FALSE 9 (to 35) 26 POP_TOP 27 POP_TOP 28 STORE_FAST 0 (e) 31 POP_TOP 5 32 JUMP_FORWARD 2 (to 37) >> 35 POP_TOP 36 END_FINALLY >> 37 LOAD_CONST 0 (None) 40 RETURN_VALUE