热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Python实用技巧,大任务切分

今天来说说,Python中的任务切分。以爬虫为例,从一个存url的txt文件中,读取其内容,我们会获取一个url列表。我们把

图片

今天来说说,Python 中的任务切分。以爬虫为例,从一个存 url 的 txt 文件中,读取其内容,我们会获取一个 url 列表。我们把这一个 url 列表称为大任务。

列表切分

在不考虑内存占用的情况下,我们对上面的大任务进行一个切分。比如我们将大任务切分成的小任务是每秒最多只访问5个URL。

import os
import timeCURRENT_DIR &#61; os.path.dirname(os.path.abspath(__file__))def read_file():file_path &#61; os.path.join(CURRENT_DIR, "url_list.txt")with open(file_path, "r", encoding&#61;"utf-8") as fs:result &#61; [i.strip() for i in fs.readlines()]return resultdef fetch(url):print(url)def run():max_count &#61; 5url_list &#61; read_file()for index in range(0, len(url_list), max_count):start &#61; time.time()fetch(url_list[index:index &#43; max_count])end &#61; time.time() - startif end < 1:time.sleep(1 - end)if __name__ &#61;&#61; &#39;__main__&#39;:run()

关键代码都在for循环里&#xff0c;首先我们通过声明range的第三个参数&#xff0c;该参数指定迭代的步长为5,这样每次index增加都是以5为基数&#xff0c;即0&#xff0c;5&#xff0c;10。。。
然后我们对url_list做切片&#xff0c;每次取其五个元素&#xff0c;这五个元素会随着index的增加不断的在改变&#xff0c;如果最后不够五个了&#xff0c;按照切片的特性这个时候就会有多少取多少了&#xff0c;不会造成索引超下标的问题。

随着url列表的增加&#xff0c;我们会发现内存的占用也在提高了。这个时候我们就需要对代码进行修改了&#xff0c;我们知道生成器是比较节省内存的空间的&#xff0c;修改之后代码变成&#xff0c;下面的这样。

生成器切分

# -*- coding: utf-8 -*-
import os
import time
from itertools import isliceCURRENT_DIR &#61; os.path.dirname(os.path.abspath(__file__))def read_file():file_path &#61; os.path.join(CURRENT_DIR, "url_list.txt")with open(file_path, "r", encoding&#61;"utf-8") as fs:for i in fs:yield i.strip()def fetch(url):print(url)def run():max_count &#61; 5url_gen &#61; read_file()while True:url_list &#61; list(islice(url_gen, 0, max_count))if not url_list:breakstart &#61; time.time()fetch(url_list)end &#61; time.time() - startif end < 1:time.sleep(1 - end)if __name__ &#61;&#61; &#39;__main__&#39;:run()

首先&#xff0c;我们修改了文件读取的方式&#xff0c;把原来读列表的形式&#xff0c;改为了生成器的形式。这样我们在调用该文件读取方法的时候大大节省了内存。

然后就是对上面for循环进行改造&#xff0c;因为生成器的特性&#xff0c;这里不适合使用for进行迭代&#xff0c;因为每一次的迭代都会消耗生成器的元素&#xff0c;通过使用itertools的islice对url_gen进行切分,islice是生成器的切片,这里我们每次切分出含有5个元素的生成器&#xff0c;因为生成器没有__len__方法所以&#xff0c;我们将其转为列表&#xff0c;然后判断列表是否为空&#xff0c;就可以知道迭代是否该结束了。

修改之后的代码&#xff0c;不管是性能还是节省内存上都大大的提高。读取千万级的文件不是问题。
除此之外&#xff0c;在使用异步爬虫的时候&#xff0c;也许会用到异步生成器切片。下面就和大家讨论&#xff0c;异步生成器切分的问题

异步生成器切分

首先先来看一个简单的异步生成器。
我们知道调用下面的代码会得到一个生成器

def foo():for i in range(20):yield i

如果在def前面加一个async&#xff0c;那么在调用的时候它就是个异步生成器了。
完整示例代码如下

import asyncio
async def foo():for i in range(20):yield iasync def run():async_gen &#61; foo()async for i in async_gen:print(i)if __name__ &#61;&#61; &#39;__main__&#39;:asyncio.run(run())

关于async for的切分有点复杂&#xff0c;这里推荐使用aiostream模块&#xff0c;使用之后代码改为下面这样

import asyncio
from aiostream import streamasync def foo():for i in range(22):yield iasync def run():index &#61; 0limit &#61; 5while True:xs &#61; stream.iterate(foo())ys &#61; xs[index:index &#43; limit]t &#61; await stream.list(ys)if not t:breakprint(t)index &#43;&#61; limitif __name__ &#61;&#61; &#39;__main__&#39;:asyncio.run(run())


推荐阅读
  • Python操作MySQL(pymysql模块)详解及示例代码
    本文介绍了使用Python操作MySQL数据库的方法,详细讲解了pymysql模块的安装和连接MySQL数据库的步骤,并提供了示例代码。内容涵盖了创建表、插入数据、查询数据等操作,帮助读者快速掌握Python操作MySQL的技巧。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • Python爬虫中使用正则表达式的方法和注意事项
    本文介绍了在Python爬虫中使用正则表达式的方法和注意事项。首先解释了爬虫的四个主要步骤,并强调了正则表达式在数据处理中的重要性。然后详细介绍了正则表达式的概念和用法,包括检索、替换和过滤文本的功能。同时提到了re模块是Python内置的用于处理正则表达式的模块,并给出了使用正则表达式时需要注意的特殊字符转义和原始字符串的用法。通过本文的学习,读者可以掌握在Python爬虫中使用正则表达式的技巧和方法。 ... [详细]
  • 树莓派语音控制的配置方法和步骤
    本文介绍了在树莓派上实现语音控制的配置方法和步骤。首先感谢博主Eoman的帮助,文章参考了他的内容。树莓派的配置需要通过sudo raspi-config进行,然后使用Eoman的控制方法,即安装wiringPi库并编写控制引脚的脚本。具体的安装步骤和脚本编写方法在文章中详细介绍。 ... [详细]
  • 本文介绍了使用Python解析C语言结构体的方法,包括定义基本类型和结构体类型的字典,并提供了一个示例代码,展示了如何解析C语言结构体。 ... [详细]
  • 本文介绍了如何在wxpython中将matplotlib图表嵌入到自定义窗体中的方法。通过调用FigureCanvasWx类,可以实现在自定义窗体中显示matplotlib图表。同时,还介绍了与此相关的一些类和参数。 ... [详细]
  • 本文介绍了为什么要使用多进程处理TCP服务端,多进程的好处包括可靠性高和处理大量数据时速度快。然而,多进程不能共享进程空间,因此有一些变量不能共享。文章还提供了使用多进程实现TCP服务端的代码,并对代码进行了详细注释。 ... [详细]
  • 本文介绍了计算机网络的定义和通信流程,包括客户端编译文件、二进制转换、三层路由设备等。同时,还介绍了计算机网络中常用的关键词,如MAC地址和IP地址。 ... [详细]
  • 展开全部下面的代码是创建一个立方体Thisexamplescreatesanddisplaysasimplebox.#Thefirstlineloadstheinit_disp ... [详细]
  • web.py开发web 第八章 Formalchemy 服务端验证方法
    本文介绍了在web.py开发中使用Formalchemy进行服务端表单数据验证的方法。以User表单为例,详细说明了对各字段的验证要求,包括必填、长度限制、唯一性等。同时介绍了如何自定义验证方法来实现验证唯一性和两个密码是否相等的功能。该文提供了相关代码示例。 ... [详细]
  • 基于dlib的人脸68特征点提取(眨眼张嘴检测)python版本
    文章目录引言开发环境和库流程设计张嘴和闭眼的检测引言(1)利用Dlib官方训练好的模型“shape_predictor_68_face_landmarks.dat”进行68个点标定 ... [详细]
  • 延迟注入工具(python)的SQL脚本
    本文介绍了一个延迟注入工具(python)的SQL脚本,包括使用urllib2、time、socket、threading、requests等模块实现延迟注入的方法。该工具可以通过构造特定的URL来进行注入测试,并通过延迟时间来判断注入是否成功。 ... [详细]
  • 基于Socket的多个客户端之间的聊天功能实现方法
    本文介绍了基于Socket的多个客户端之间实现聊天功能的方法,包括服务器端的实现和客户端的实现。服务器端通过每个用户的输出流向特定用户发送消息,而客户端通过输入流接收消息。同时,还介绍了相关的实体类和Socket的基本概念。 ... [详细]
  • 本文介绍了在Cpp中将字符串形式的数值转换为int或float等数值类型的方法,主要使用了strtol、strtod和strtoul函数。这些函数可以将以null结尾的字符串转换为long int、double或unsigned long类型的数值,且支持任意进制的字符串转换。相比之下,atoi函数只能转换十进制数值且没有错误返回。 ... [详细]
  • 本文介绍了解决java开源项目apache commons email简单使用报错的方法,包括使用正确的JAR包和正确的代码配置,以及相关参数的设置。详细介绍了如何使用apache commons email发送邮件。 ... [详细]
author-avatar
万万558
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有