上QQ阅读APP看书,第一时间看更新
2.14.1 基本语法
当我们在浏览器里尝试访问不存在的网址时,浏览器会报错,告诉我们地址不存在。当我们用Python代码尝试访问不存在的网址时,代码也会报错。
用requests模块,成功访问bing.com:
>>> import requests >>> requests.get('http://www.bing.com') <Response [200]>
访问一个不存在的网址http://www.bingbingbangbang.com,有异常发生:
>>> requests.get('http://www.bingbingbangbang.com') Traceback (most recent call last): ...... r = adapter.send(request, **kwargs) File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site- packages/requests/adapters.py", line 508, in send raise ConnectionError(e, request=request) requests.exceptions.ConnectionError: HTTPConnectionPool(host='www. bingbingbangbang.com', port=80): Max retries exceeded with url: / (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x1018a1128>: Failed to establish a new connection: [Errno 8] nodename nor servname provided, or not known',))
这只是截取后的片段,原始的错误信息更冗长。在很多应用场合,我们并不想看到这么具体的错误信息,更不想让程序就此崩溃,我们只是想知道网址是否可以正确访问。比如,hao123.com网站页面聚合了大量的网址链接,如果想知道其中是否有异常链接,我们可以逐一访问检测,但是如果有访问异常发生,我们不希望程序崩溃,不希望后续的检测被影响。
我们来尝试用异常处理来重构代码,把可能出错的代码放在try代码块中,把错误处理的逻辑放在except代码块中,异常发生的时候会被捕获,程序执行会立刻转到except代码块中。
try: do_something() except: print("Something bad happened")
用异常处理来重构网页的访问。
import requests urls = [ 'http://www.bing.com', 'http://www.bingbingbangbang.com', 'http://www.yahoo.com' ] for url in urls: try: requests.get(url) print('SUCCESS:', url) except: print('FAILED: ', url)
执行结果如下:
SUCCESS: http://www.bing.com FAILED: http://www.bingbingbangbang.com SUCCESS: http://www.yahoo.com
通常情况下,我们会用except...as捕获异常对象,获取具体的错误信息,以便后续排查分析。
variables = ['11', '-12', '33.3', '二十一'] for variable in variables: try: int_variable = int(variable) except Exception as err: print('Failed in casting "{}" to integer'.format(variable)) print(err) print()
执行结果如下:
Failed in casting "33.3" to integer invalid literal for int() with base 10: '33.3' Failed in casting "二十一" to integer invalid literal for int() with base 10: '二十一'
当异常发生的时候,try代码块里出错点以后的代码都不会被执行,程序执行逻辑会转到except代码块里面去。
try: print('aa') print('bb') c = 12 + '21' print('dd') except: print('error happened!!!')
执行结果如下:
aa bb error happened!!!
我们可以用finally来指明try/except之后执行的逻辑,不管有没有异常发生,finally中的代码都会被执行。比如,在建立了数据库连接之后执行查询操作,不管查询操作是不是有异常发生,我们都希望在查询操作结束之后把数据库连接关掉,这种情况可以在finally代码块中执行关闭数据库连接的操作。
try: print('aa') print('bb') c = 12 + '21' print('dd') except: print('error happened!') finally: print('It is over anyway')
执行结果如下:
aa bb error happened! It is over anyway