response.end后抛了异常_如何用异常

何时用异常,何时不用,这个问题一直萦绕在我心头。直到看到这个视频,答案不能再清晰了。

https://www.youtube.com/watch?v=UsrHQAzSXkA​www.youtube.com

b0ba0ceac0b28003d05def840f38cba1.png

关键点虽然只有我截下来这一屏,所以还是需要我再展开说明一下。引用我以前的问题

一般来说写代码时函数不能足前条件和后条件时抛出异常很合理。但在设计函数时,是扩大前条件,当不满足时抛异常,还是减小前条件,尽量不抛异常?
像返回错误码,或expect一样的接口,可以认为后条件已经包括所有情况,理论上也可以不抛出异常。
从调用方来分析,入参范围应该尽量小,编译时能检查最好;出参应该在保持状态一致的情况下,尽可能范围大,包括一些不完全出错的情况,比如返回空容器,返回哨兵等,从而少抛异常。但不应把出错情况都定义到返回值中,那就把功能接口定义成了检查接口。
部分功能本身就有尝试的情况,那么就可以通过重载,把这种情况从正常的情况中区分处理,返回失败供检查。类似的接口如std::filesystem

有了问题,答案就很明确了。

如果函数不能满足前条件,断言失败。不要扩大前条件,增加需要检查的范围。也不要减少前条件,让调用方做过多的准备工作。满足前条件是调用方的责任,是bug,要修。

函数的后条件应该包括错误的情况,返回错误码和异常都可以,都满足后条件。通过异常或错误码,把错误情况和正常情况中区分出来。如果抛异常,那么不再需要返回错误码,即可以简单的省去返回值中错误值的部分。有返回错误码又抛异常的函数行为有错误。

函数应该总是满足后条件,当且仅当,返回成功时,才可能出现不满足后的情况。这种情况是函数自身的bug,要修。调用方可以放心地断言调用结果满足后条件。

这个解释其实倾向于使用异常。因为按这个解析,前条件由调用方保证,必须在调用之前检查参数有效性,错误处理代码会与正常路径混在一起,非常不好看。

import http.client from html.parser import HTMLParser import argparse from concurrent.futures import ThreadPoolExecutor import multiprocessing.pool prefix = "save/" readed_path = multiprocessing.Manager().list() cur_path = multiprocessing.Manager().list() new_path = multiprocessing.Manager().list() lock = multiprocessing.Lock() class MyHttpParser(HTMLParser): def __init__(self): HTMLParser.__init__(self) self.tag = [] self.href = "" self.txt = "" def handle_starttag(self, tag, attrs): self.tag.append(tag) # print("start tag in list :" + str(self.tag)) if tag == "a": for att in attrs: if att[0] == 'href': self.href = att[1] def handle_endtag(self, tag): if tag == "a" and len(self.tag) > 2 and self.tag[-2] == "div": print("in div, link txt is %s ." % self.txt) print("in div, link url is %s ." % self.href) lock.acquire() if not self.href in readed_path: readed_path.append(self.href) new_path.append(self.href) # print("end tag in list :" + str(self.tag)) lock.release() self.tag.pop(-1) def handle_data(self, data): if len(self.tag) >= 1 and self.tag[-1] == "a": self.txt = data def LoadHtml(path, file_path): if len(file_path) == 0: file_path = "/" conn = http.client.HTTPConnection(path) try: conn.request("GET", file_path) response = conn.getresponse() print(response.status, response.reason, response.version) data = response.read().decode("utf-8") if response.status == 301: data = response.getheader("Location") lock.acquire() new_path.append(data) lock.release() data = "" #print(data) conn.close() return data except Exception as e: print(e.args) def ParseArgs(): # 初始化解析器 parser = argparse.ArgumentParser() # 定义参数 parser.add_argument("-p", "--path", help="域名") parser.add_argument("-d", "--deep", type=int, help="递归深度") # 解析 args = parser.parse_args() return args def formatPath(path): path = path.removeprefix("https://") path = path.removeprefix("http://") path = path.removeprefix("//") return path def doWork(path): path = formatPath(path) m = path.find("/") if m == -1: m = len(path) data = LoadHtml(path[:m], path[m:]) with open(prefix + path[:m] + ".html", "w+", encoding="utf-8") as f: f.write(data) parse.feed(data) def work(deep,maxdeep): if deep > maxdeep: return args = ParseArgs() cur_path.append(formatPath(args.path)) readed_path.append(formatPath(args.path)) parse = MyHttpParser() e = multiprocessing.Pool(4) for i in range(args.deep): size = len(cur_path) e.map(doWork,cur_path) cur_path[:]=[] for p in new_path: cur_path.append(p) new_path[:]=[] print(i)优化此代码能在windows下运行
最新发布
06-03
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值