最近在学Python,简单看了点特性和基础语法就开始自己写一个爬虫,目标是爬本博客。
项目github地址
因为写的时候参考的是github上的CrawlerHot爬虫项目,里面用到了with as语法写入文件,
开始只是初略了解到了如果用with as写文件的话是不需要file.close()。
然后继续跟着项目用了with as来执行ThreadPoolExecutor开线程来执行任务,但是没有深入了解为什么。
原.png
根据上图81行我原本是执行了shutdown(),但后面经网友指点了下with as的话是需不需要pool.shutdown()的,因为上下文管理器会自动帮你执行。
我就想上下文管理器是个什么? 但是感觉和之前写入文件时不需要file.close()有异曲同工之妙。

首先来看看官方文档
with 语句用于包装带有使用上下文管理器 (参见 with 语句上下文管理器 一节) 定义的方法的代码块的执行。 这允许对普通的 try...except...finally 使用模式进行封装以方便地重用。

with_stmt ::=  "with" with_item ("," with_item)* ":" suite
with_item ::=  expression ["as" target]

带有一个“项目”的 with 语句的执行过程如下:

1.对上下文表达式 (在 with_item 中给出的表达式) 求值以获得一个上下文管理器。
2.载入上下文管理器的 __exit__() 以便后续使用。
3.发起调用上下文管理器的 __enter__() 方法。
4.如果 with 语句中包含一个目标,来自 __enter__() 的返回值将被赋值给它。

注解
with 语句会保证如果 __enter__() 方法返回时未发生错误,则 __exit__() 将总是被调用。 因此,如果在对目标列表赋值期间发生错误,则会将其视为在语句体内部发生的错误。 参见下面的第 6 步。

5.执行语句体。
6.发起调用上下文管理器的 __exit__() 方法。 如果语句体的退出是由异常导致的,则其类型、值和回溯信息将被作为参数传递给 __exit__()。 否则的话,将提供三个 None 参数。

如果语句体的退出是由异常导致的,并且来自 __exit__() 方法的返回值为假,则该异常会被重新引发。 如果返回值为真,则该异常会被抑制,并会继续执行 with 语句之后的语句。
如果语句体由于异常以外的任何原因退出,则来自 __exit__() 的返回值会被忽略,并会在该类退出正常的发生位置继续执行。


大致意思呢就是使用with的话在某些情况下会按顺序调用 __enter__()、__exit__()方法,
那这个方法是在哪呢?
注意原文 带有使用上下文管理器定义的方法的代码块

通过dir()方法看到ThreadPoolExecutor是有__exit__这个方法的。
ddddd20190822140517.png

其次通过IDE代码追踪看。
20190822135527.png

ctrl+左键跳转看到是做了shoutdown()的。
微信图片_20190822135616.png

标签: none

添加新评论