前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >零基础学编程023:用with实现优雅地释放资源

零基础学编程023:用with实现优雅地释放资源

作者头像
申龙斌
发布2018-03-06 10:54:04
1K0
发布2018-03-06 10:54:04
举报

在《零基础学编程022:函数的世界》中我们写了一个函数,通过访问新浪的实时行情服务,得到股票的开盘价。

代码语言:javascript
复制
import urllib.request as req

def price(stock) :
    url = 'http://hq.sinajs.cn/list=' + stock
    with req.urlopen(url) as f :
        hq = f.read().decode('GBK')
        v = hq.split(',')
        return v[1]

新手对 with 的用法不太理解,如果以前学过C#语言,这个with类似于using关键词。先来看看不太好的写法吧:

代码语言:javascript
复制
import urllib.request as req

def price(stock) :
    url = 'http://hq.sinajs.cn/list=' + stock
    f = req.urlopen(url)   # 尽量不要用这种写法!
    hq = f.read().decode('GBK')
    v = hq.split(',')
    f.close() # 当前面发生异常时,不一定能够执行到这条语句
    return v[1]

上面这段代码没有用 with ... as ... 的写法,而是用赋值语句把req.urlopen(url)赋给了 f,在返回开盘价 return v[1] 之前调用了 f.close() 把网络连接关闭。

在绝大多数情况下,这种代码不会有什么问题。但这里的代码访问了网络,而访问网络会有各种异常情况,比如网卡被禁用、WIFI未连接、无法连接互联网、网络地址无效、代理设置不正确、网络服务器故障、防火墙阻挡等等,这些异常都是编程之前无法完全预料的。

我们调用 urlopen() 打开了一个网络连接,在最后务必要保证把它关闭,即调用close() 函数。但当网络已经发生异常了,此时还未执行到close() 函数,程序就已经异常退出了,所以网络连接可能仍处于打开状态。

一般的小程序,这少量的未关闭的网络连接并不会造成什么麻烦,有时操作系统还会在进程关闭时自动释放这些连接,但如果编写服务端程序时,几秒钟之内就可能产生数千个并发连接,当这种问题积累到一定程度后,程序就会出现莫名其妙的错误,而且这种错误特别难定位。

我在2002年用java写过一个网络信息发布系统,当时有人的代码里没有正确地释放Oracle数据库连接,当正式上线时,几分钟之内产生了数百个未释放的数据库连接,Oralce主数据库差点宕掉,幸好我们及时地把程序摘掉,才避免了一次事故的发生。

所以学习编程时,一定要参考别人的例子代码,尤其是参考官方的例子代码。网上流传的一些核心代码只是为了说明具体的用法,写法上并不规范,也没有加入异常处理的相关代码,而真正产品级的代码,会加上许多边界条件检查、异常判断的语句,从而让产品更加健壮。

小结:

  • with 语句用于保证一些资源(文件、网络连接、数据库等)在发生异常时能够正常地关闭或释放
  • 编程初期就养成良好地编程习惯,将错误扼杀在摇篮里
  • with 语句内部会自动调用close()语句释放网络连接,其背后还有比较复杂的实现机制,以后再说

--- END ---

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-02-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 申龙斌的程序人生 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云开发 CloudBase
云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为200万+企业和开发者提供高可用、自动弹性扩缩的后端云服务,可用于云端一体化开发多种端应用(小程序、公众号、Web 应用等),避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档