处理Python中其他库导入的库的异常的最佳实践?

处理Python中其他库导入的库的异常的最佳实践?,python,exception,exception-handling,suds,Python,Exception,Exception Handling,Suds,处理Python中其他库导入的库中的异常的适当方法是什么 例如,我有一个名为“pycontrol”的库,我将它导入到我的主程序中。“pycontrol”导入“suds”库。“suds”库依次导入“urllib2”库。我注意到,当“suds”库无法连接到通过“urllib2”访问的远程资源时,这些异常会逐渐进入我的主程序 此时,我的最佳猜测是将urllib2和SUD导入到我的全局名称空间中,并捕获它们引发的典型异常,这些异常在“pycontrol”中没有处理 关于如何实现这一点,是否有其他最佳实践

处理Python中其他库导入的库中的异常的适当方法是什么

例如,我有一个名为“pycontrol”的库,我将它导入到我的主程序中。“pycontrol”导入“suds”库。“suds”库依次导入“urllib2”库。我注意到,当“suds”库无法连接到通过“urllib2”访问的远程资源时,这些异常会逐渐进入我的主程序

此时,我的最佳猜测是将urllib2和SUD导入到我的全局名称空间中,并捕获它们引发的典型异常,这些异常在“pycontrol”中没有处理

关于如何实现这一点,是否有其他最佳实践

代码片段外观的基本概念(无需将sud或urllib2导入全局名称空间):

将pycontrol.pycontrol作为pc导入
打印“连接到LTM%s上的iControl API…”%LTM
尝试:
b=pc.BIGIP(主机名=ltm,用户名=user,密码=pw,
wsdls=wsdl_列表,fromurl=True,
调试=soap\u调试)
除()外,详情:
打印“错误:无法连接到LTM%s上的iControl API…正在中止!”%LTM
打印“详细信息:%s”%detail
exitcode=1
其他:
打印“已成功建立连接”
下面是一个样本回溯:

Connecting to iControl API on LTM s0-bigip1-lb2.lab.zynga.com...
Traceback (most recent call last):
  File "./register.py", line 507, in <module>
    main()
  File "./register.py", line 415, in main
    b = build_bigip_object(ltm, user, pw, WSDLS, soap_debug = False)
  File "./register.py", line 85, in build_bigip_object
    debug=soap_debug)
  File "build/bdist.macosx-10.6-universal/egg/pycontrol/pycontrol.py", line 81, in __init__
  File "build/bdist.macosx-10.6-universal/egg/pycontrol/pycontrol.py", line 103, in _get_clients
  File "build/bdist.macosx-10.6-universal/egg/pycontrol/pycontrol.py", line 149, in _get_suds_client
  File "/Library/Python/2.6/site-packages/suds/client.py", line 111, in __init__
    self.wsdl = reader.open(url)
  File "/Library/Python/2.6/site-packages/suds/reader.py", line 136, in open
    d = self.fn(url, self.options)
  File "/Library/Python/2.6/site-packages/suds/wsdl.py", line 136, in __init__
    d = reader.open(url)
  File "/Library/Python/2.6/site-packages/suds/reader.py", line 73, in open
    d = self.download(url)
  File "/Library/Python/2.6/site-packages/suds/reader.py", line 88, in download
    fp = self.options.transport.open(Request(url))
  File "/Library/Python/2.6/site-packages/suds/transport/https.py", line 60, in open
    return  HttpTransport.open(self, request)
  File "/Library/Python/2.6/site-packages/suds/transport/http.py", line 62, in open
    return self.u2open(u2request)
  File "/Library/Python/2.6/site-packages/suds/transport/http.py", line 118, in u2open
    return url.open(u2request, timeout=tm)
  File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/urllib2.py", line 383, in open
    response = self._open(req, data)
  File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/urllib2.py", line 401, in _open
    '_open', req)
  File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/urllib2.py", line 361, in _call_chain
    result = func(*args)
  File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/urllib2.py", line 1138, in https_open
    return self.do_open(httplib.HTTPSConnection, req)
  File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/urllib2.py", line 1105, in do_open
    raise URLError(err)
urllib2.URLError: <urlopen error [Errno 8] nodename nor servname provided, or not known>
连接到LTM s0-bigip1-lb2.lab.zynga.com上的iControl API。。。
回溯(最近一次呼叫最后一次):
文件“/register.py”,第507行,在
main()
文件“/register.py”,第415行,主
b=构建\u bigip\u对象(ltm、用户、pw、WSDLS、soap\u调试=False)
文件“/register.py”,第85行,在build\u bigip\u对象中
调试=soap\u调试)
文件“build/bdist.macosx-10.6-universal/egg/pycontrol/pycontrol.py”,第81行,在__
文件“build/bdist.macosx-10.6-universal/egg/pycontrol/pycontrol.py”,第103行,在“获取客户机”中
文件“build/bdist.macosx-10.6-universal/egg/pycontrol/pycontrol.py”,第149行,在“获取”suds\u client中
文件“/Library/Python/2.6/site packages/suds/client.py”,第111行,在__
self.wsdl=reader.open(url)
文件“/Library/Python/2.6/site packages/suds/reader.py”,第136行,打开
d=self.fn(url,self.options)
文件“/Library/Python/2.6/site packages/suds/wsdl.py”,第136行,在__
d=读卡器。打开(url)
文件“/Library/Python/2.6/site packages/suds/reader.py”,第73行,打开
d=自我下载(url)
下载文件“/Library/Python/2.6/site packages/suds/reader.py”,第88行
fp=self.options.transport.open(请求(url))
文件“/Library/Python/2.6/site packages/suds/transport/https.py”,第60行,打开
返回HttpTransport.open(self,request)
文件“/Library/Python/2.6/site packages/suds/transport/http.py”,第62行,打开
返回self.u2open(u2request)
文件“/Library/Python/2.6/site packages/suds/transport/http.py”,第118行,在u2open中
返回url.open(u2request,timeout=tm)
文件“/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/urllib2.py”,第383行,打开
响应=自身打开(请求,数据)
文件“/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/urllib2.py”,第401行,打开
"开放",
文件“/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/urllib2.py”,第361行,在调用链中
结果=func(*args)
https_open中的文件“/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/urllib2.py”,第1138行
返回self.do_open(httplib.HTTPSConnection,req)
文件“/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/urllib2.py”,第1105行,打开
引发URL错误(err)
urllib2.URLError:

我想你回答了你自己的问题。导入urllib2并捕获模块中的异常

from urllib2 import URLError

try:
    # something
except URLError, e:
    # Do something in case of error.

为什么您需要捕获特定的异常?毕竟,从
b=pc.BIGIP(…)
引发的任何异常(不仅仅是
URLError
)都意味着您无法继续

我建议:

import traceback

try:
    b = pc.BIGIP(...)
except:
    traceback.print_exc()
    exitcode = 1
else:
    do_something_with_connection(b)
另一个想法是:为什么要费心捕捉异常呢?Python解释器将堆栈跟踪转储到stderr,并在遇到未处理的异常时退出程序:

b = bc.BIGIP(...)
do_something_with_connection(b)
或者,如果需要写入错误日志:

import logging
import sys

def main():
   b = bc.BIGIP(...)
   do_something_with_connection(b)

if __name__ == "__main__":
    try:
        main()
    except:
        logging.exception("An unexpected error occured")
        sys.exit(1)

谢谢你的建议。异常本身实际上传递了有关远程API发生了什么的有用信息。有时异常实际上是非致命的,当远程API操作失败时,我只需要做一些合乎逻辑的事情。这就是我所想的(并且一直在做的)。我想我认为有一种更“蟒蛇式”的方法来处理这个问题。似乎我也不应该担心是什么引发了异常,只需要捕获从我试图使用的库(pycontrol)调用引发的任何异常。不完全是——只捕获您准备处理的异常。如果您不能使用ValueError做任何有用的事情,那么捕获它就没有意义了。
import logging
import sys

def main():
   b = bc.BIGIP(...)
   do_something_with_connection(b)

if __name__ == "__main__":
    try:
        main()
    except:
        logging.exception("An unexpected error occured")
        sys.exit(1)