2010-12-18 118 views
4

它看起来像我没有很好的异常处理呢。我茫然:( 下面的代码有时会返回此错误:Python尝试除了最后

File "applications/pingback/modules/plugin_h_pingback.py", line 190, in ping 
    db(table.id==id_).update(status=status) 
UnboundLocalError: local variable 'status' referenced before assignment 

我希望status总是被分配一个值,难道是因为一些其他的异常被抛出(或许在内心try)和finally掩盖呢?

... 
try: 
    server_url = self._get_pingback_server(target) 
except PingbackClientError, e: 
    status = e.message 
else: 
    try: 
     server = xmlrpclib.ServerProxy(server_url) 
     status = server.pingback.ping(self.source, target) 
    except xmlrpclib.Fault, e: 
     status = e 
finally: 
    db(table.id==id_).update(status=status) # <-- UnboundLocalError 
... 

感谢,HC

回答

9

您的代码不会始终分配东西的状态。我能看到的几种方法这种地位可能不分配我和埃德已经强调他们下面:

try: 
    server_url = self._get_pingback_server(target) 
except PingbackClientError, e: 
    # If evaluating `e.message` raises an exception then status is not set. 
    status = e.message # <--- here 
else: 
    try: 
     # If either of these two lines fails with something other than 
     # xmlrcplib.Fault, then status is not set. 
     server = xmlrpclib.ServerProxy(server_url)    # <--- here 
     status = server.pingback.ping(self.source, target)  # <--- here 
    # If xmlrpclib.Fault is not defined status is not set. 
    except xmlrpclib.Fault, e:         # <--- here 
     status = e 
finally: 
    db(table.id==id_).update(status=status) 

我怀疑该错误的最可能的地方是在内部try块下,如果只抓住xmlrpclib.Fault而不是其他类型的异常。

+0

感谢马克。因此,如果finally块自身失败,那么finally会有效地隐藏try块中其他地方引发的未捕获异常,因为它的块总是被执行? – hcvst 2010-12-18 09:03:06

+2

“隐藏”意思是暂时拦截它,然后只有当finally块没有自己的异常提升时才转发它。 – 2010-12-18 17:47:42

3

作为一个简单的解决方案,我会初始化状态的任何模块外:

status = None 
try: 
    # etc 

然后状态将永远被束缚。这不会解决任何未处理的异常的问题,但它将解决UnboundLocalError。

(另外,在第一块你assing状态与e.message,在下面的块,你只需要使用完整的误差e,而不仅仅是消息。)