当前位置: 首页 > news >正文

网站加载慢图片做延时加载有用百度霸屏推广多少钱一个月

网站加载慢图片做延时加载有用,百度霸屏推广多少钱一个月,小说推广怎么做,中国室内设计联盟官网首页前言在这个世界上#xff0c;人们每天都在用 Python 完成着不同的工作。而文件操作#xff0c;则是大家最常需要解决的任务之一。使用 Python#xff0c;你可以轻松为他人生成精美的报表#xff0c;也可以用短短几行代码快速解析、整理上万份数据文件。当我们编写与文件相关…前言在这个世界上人们每天都在用 Python 完成着不同的工作。而文件操作则是大家最常需要解决的任务之一。使用 Python你可以轻松为他人生成精美的报表也可以用短短几行代码快速解析、整理上万份数据文件。当我们编写与文件相关的代码时通常会关注这些事情我的代码是不是足够快我的代码有没有事半功倍的完成任务 在这篇文章中我会与你分享与之相关的几个编程建议。我会向你推荐一个被低估的 Python 标准库模块、演示一个读取大文件的最佳方式、最后再分享我对函数设计的一点思考。下面让我们进入第一个“模块安利”时间吧。建议一如果你需要在 Python 里进行文件处理那么标准库中的 os 和 os.path 兄弟俩一定是你无法避开的两个模块。在这两个模块里有着非常多与文件路径处理、文件读写、文件状态查看相关的工具函数。让我用一个例子来展示一下它们的使用场景。有一个目录里装了很多数据文件但是它们的后缀名并不统一既有 .txt又有 .csv。我们需要把其中以 .txt 结尾的文件都修改为 .csv 后缀名。我们可以写出这样一个函数import os import os.pathdef unify_ext_with_os_path(path):统一目录下的 .txt 文件名后缀为 .csvfor filename in os.listdir(path):basename, ext os.path.splitext(filename)if ext .txt:abs_filepath os.path.join(path, filename)os.rename(abs_filepath, os.path.join(path, f{basename}.csv)) 让我们看看上面的代码一共用到了哪些与文件处理相关的函数os.listdir(path)列出 path 目录下的所有文件含文件夹os.path.splitext(filename)切分文件名里面的基础名称和后缀部分os.path.join(path,filename)组合需要操作的文件名为绝对路径os.rename(...)重命名某个文件上面的函数虽然可以完成需求但说句实话即使在写了很多年 Python 代码后我依然觉得这些函数不光很难记而且最终的成品代码也不怎么讨人喜欢。使用 pathlib 模块改写代码为了让文件处理变得更简单Python 在 3.4 版本引入了一个新的标准库模块pathlib。它基于面向对象思想设计封装了非常多与文件操作相关的功能。如果使用它来改写上面的代码结果会大不相同。使用 pathlib 模块后的代码from pathlib import Pathdef unify_ext_with_pathlib(path):for fpath in Path(path).glob(*.txt):fpath.rename(fpath.with_suffix(.csv)) 和旧代码相比新函数只需要两行代码就完成了工作。而这两行代码主要做了这么几件事首先使用 Path(path) 将字符串路径转换为 Path 对象调用 .glob(*.txt) 对路径下所有内容进行模式匹配并以生成器方式返回结果仍然是 Path 对象所以我们可以接着做后面的操作使用 .with_suffix(.csv) 直接获取使用新后缀名的文件全路径调用 .rename(target) 完成重命名相比 os 和 os.path引入 pathlib 模块后的代码明显更精简也更有整体统一感。所有文件相关的操作都是一站式完成。其他用法除此之外pathlib 模块还提供了很多有趣的用法。比如使用 / 运算符来组合文件路径# 旧朋友使用 os.path 模块import os.pathos.path.join(/tmp, foo.txt) /tmp/foo.txt# ✨ 新潮流使用 / 运算符from pathlib import PathPath(/tmp) / foo.txtPosixPath(/tmp/foo.txt) 或者使用 .read_text() 来快速读取文件内容# 标准做法使用 with open(...) 打开文件with open(foo.txt) as file: ... print(file.read()) ... foo# 使用 pathlib 可以让这件事情变得更简单from pathlib import Pathprint(Path(foo.txt).read_text()) foo 除了我在文章里介绍的这些pathlib 模块还提供了非常多有用的方法强烈建议去 官方文档 详细了解一下。如果上面这些都不足以让你动心那么我再多给你一个使用 pathlib 的理由PEP-519 里定义了一个专门用于“文件路径”的新对象协议这意味着从该 PEP 生效后的 Python 3.6 版本起pathlib 里的 Path 对象可以和以前绝大多数只接受字符串路径的标准库函数兼容使用 p Path(/tmp) # 可以直接对 Path 类型对象 p 进行 joinos.path.join(p, foo.txt) /tmp/foo.txt 所以无需犹豫赶紧把 pathlib 模块用起来吧。建议二几乎所有人都知道在 Python 里读取文件有一种“标准做法”首先使用 withopen(fine_name) 上下文管理器的方式获得一个文件对象然后使用 for 循环迭代它逐行获取文件里的内容。下面是一个使用这种“标准做法”的简单示例函数def count_nine(fname):计算文件里包含多少个数字 9count 0with open(fname) as file:for line in file:count line.count(9)return count 假如我们有一个文件 small_file.txt那么使用这个函数可以轻松计算出 9 的数量。# small_file.txtfeiowe9322nasd9233rlaoeijfiowejf8322kaf9a# OUTPUT: 3print(count_nine(small_file.txt)) 为什么这种文件读取方式会成为标准这是因为它有两个好处with 上下文管理器会自动关闭打开的文件描述符在迭代文件对象时内容是一行一行返回的不会占用太多内存标准做法的缺点但这套标准做法并非没有缺点。如果被读取的文件里根本就没有任何换行符那么上面的第二个好处就不成立了。当代码执行到 forlineinfile 时line 将会变成一个非常巨大的字符串对象消耗掉非常可观的内存。让我们来做个试验有一个 5GB 大的文件 big_file.txt它里面装满了和 small_file.txt 一样的随机字符串。只不过它存储内容的方式稍有不同所有的文本都被放在了同一行里# FILE: big_file.txt df2if283rkwefh... 剩余 5GB 大小 ...如果我们继续使用前面的 count_nine 函数去统计这个大文件里 9 的个数。那么在我的笔记本上这个过程会足足花掉 65 秒并在执行过程中吃掉机器 2GB 内存。为了解决这个问题我们需要暂时把这个“标准做法”放到一边使用更底层的 file.read() 方法。与直接循环迭代文件对象不同每次调用 file.read(chunk_size) 会直接返回从当前位置往后读取 chunk_size 大小的文件内容不必等待任何换行符出现。所以如果使用 file.read() 方法我们的函数可以改写成这样:def count_nine_v2(fname):计算文件里包含多少个数字 9每次读取 8kbcount 0block_size 1024 * 8with open(fname) as fp:while True:chunk fp.read(block_size)# 当文件没有更多内容时read 调用将会返回空字符串 if not chunk:breakcount chunk.count(9)return count在新函数中我们使用了一个 while 循环来读取文件内容每次最多读取 8kb 大小这样可以避免之前需要拼接一个巨大字符串的过程把内存占用降低非常多。利用生成器解耦代码假如我们在讨论的不是 Python而是其他编程语言。那么可以说上面的代码已经很好了。但是如果你认真分析一下 count_nine_v2 函数你会发现在循环体内部存在着两个独立的逻辑数据生成read 调用与 chunk 判断 与 数据消费。而这两个独立逻辑被耦合在了一起。正如我在《编写地道循环》里所提到的为了提升复用能力我们可以定义一个新的 chunked_file_reader 生成器函数由它来负责所有与“数据生成”相关的逻辑。这样 count_nine_v3 里面的主循环就只需要负责计数即可。def chunked_file_reader(fp, block_size1024 * 8):生成器函数分块读取文件内容while True:chunk fp.read(block_size)# 当文件没有更多内容时read 调用将会返回空字符串 if not chunk:breakyield chunkdef count_nine_v3(fname):count 0with open(fname) as fp:for chunk in chunked_file_reader(fp):count chunk.count(9)return count进行到这一步代码似乎已经没有优化的空间了但其实不然。iter(iterable) 是一个用来构造迭代器的内建函数但它还有一个更少人知道的用法。当我们使用 iter(callable,sentinel) 的方式调用它时会返回一个特殊的对象迭代它将不断产生可调用对象 callable 的调用结果直到结果为 setinel 时迭代终止。def chunked_file_reader(file, block_size1024 * 8):生成器函数分块读取文件内容使用 iter 函数 # 首先使用 partial(fp.read, block_size) 构造一个新的无需参数的函数# 循环将不断返回 fp.read(block_size) 调用结果直到其为 时终止for chunk in iter(partial(file.read, block_size), ):yield chunk最终只需要两行代码我们就完成了一个可复用的分块文件读取函数。那么这个函数在性能方面的表现如何呢和一开始的 2GB 内存/耗时 65 秒 相比使用生成器的版本只需要 7MB 内存 / 12 秒 就能完成计算。效率提升了接近 4 倍内存占用更是不到原来的 1%。建议三统计完文件里的 “9” 之后让我们换一个需求。现在我想要统计每个文件里出现了多少个英文元音字母aeiou。只要对之前的代码稍作调整很快就可以写出新函数 count_vowels。):统计某个文件中包含元音字母(aeiou)的数量VOWELS_LETTERS {a, e, i, o, u}count 0with open(filename, r) as fp:for line in fp:for char in line:if char.lower() in VOWELS_LETTERS:count 1return count# OUTPUT: 16 print(count_vowels(small_file.txt))和之前“统计 9”的函数相比新函数变得稍微复杂了一些。为了保证程序的正确性我需要为它写一些单元测试。但当我准备写测试时却发现这件事情非常麻烦主要问题点如下函数接收文件路径作为参数所以我们需要传递一个实际存在的文件为了准备测试用例我要么提供几个样板文件要么写一些临时文件而文件是否能被正常打开、读取也成了我们需要测试的边界情况如果你发现你的函数难以编写单元测试那通常意味着你应该改进它的设计。上面的函数应该如何改进呢答案是让函数依赖“文件对象”而不是文件路径。修改后的函数代码如下def count_vowels_v2(fp):统计某个文件中包含元音字母(aeiou)的数量VOWELS_LETTERS {a, e, i, o, u}count 0for line in fp:for char in line:if char.lower() in VOWELS_LETTERS:count 1return count# 修改函数后打开文件的职责被移交给了上层函数调用者 with open(small_file.txt) as fp:print(count_vowels_v2(fp))这个改动带来的主要变化在于它提升了函数的适用面。因为 Python 是“鸭子类型”的虽然函数需要接受文件对象但其实我们可以把任何实现了文件协议的 “类文件对象file-like object” 传入 count_vowels_v2 函数中。而 Python 中有着非常多“类文件对象”。比如 io 模块内的 StringIO 对象就是其中之一。它是一种基于内存的特殊对象拥有和文件对象几乎一致的接口设计。利用 StringIO我们可以非常方便的为函数编写单元测试。# 注意以下测试函数需要使用 pytest 执行 import pytest from io import StringIOpytest.mark.parametrize(content,vowels_count, [# 使用 pytest 提供的参数化测试工具定义测试参数列表# (文件内容, 期待结果)(, 0),(Hello World!, 3),(HELLO WORLD!, 3),(你好世界, 0),] ) def test_count_vowels_v2(content, vowels_count):# 利用 StringIO 构造类文件对象 filefile StringIO(content)assert count_vowels_v2(file) vowels_count使用 pytest 运行测试可以发现函数可以通过所有的用例❯ pytest vowels_counter.pytest session starts collected 4 itemsvowels_counter.py ... [100%] 4 passed in 0.06 seconds 而让编写单元测试变得更简单并非修改函数依赖后的唯一好处。除了 StringIO 外subprocess 模块调用系统命令时用来存储标准输出的 PIPE 对象也是一种“类文件对象”。这意味着我们可以直接把某个命令的输出传递给 count_vowels_v2 函数来计算元音字母数import subprocess# 统计 /tmp 下面所有一级子文件名目录名有多少元音字母 p subprocess.Popen([ls, /tmp], stdoutsubprocess.PIPE, encodingutf-8)# p.stdout 是一个流式类文件对象可以直接传入函数 # OUTPUT: 42 print(count_vowels_v2(p.stdout))正如之前所说将函数参数修改为“文件对象”最大的好处是提高了函数的 适用面 和 可组合性。通过依赖更为抽象的“类文件对象”而非文件路径给函数的使用方式开启了更多可能StringIO、PIPE 以及任何其他满足协议的对象都可以成为函数的客户。不过这样的改造并非毫无缺点它也会给调用方带来一些不便。假如调用方就是想要使用文件路径那么就必须得自行处理文件的打开操作。如何编写兼容二者的函数有没有办法即拥有“接受文件对象”的灵活性又能让传递文件路径的调用方更方便答案是有而且标准库中就有这样的例子。打开标准库里的 xml.etree.ElementTree 模块翻开里面的 ElementTree.parse 方法。你会发现这个方法即可以使用文件对象调用也接受字符串的文件路径。而它实现这一点的手法也非常简单易懂def parse(self, source, parserNone):*source* is a file name or file object, *parser* is an optional parserclose_source False# 通过判断 source 是否有 read 属性来判定它是不是“类文件对象”# 如果不是那么调用 open 函数打开它并负担起在函数末尾关闭它的责任if not hasattr(source, read):source open(source, rb)close_source True使用这种基于“鸭子类型”的灵活检测方式 count_vowels_v2 函数也同样可以被改造得更方便我在这里就不再重复啦。总结文件操作我们在日常工作中经常需要接触的领域使用更方便的模块、利用生成器节约内存以及编写适用面更广的函数可以让我们编写出更高效的代码。让我们最后再总结一下吧使用 pathlib 模块可以简化文件和目录相关的操作并让代码更直观PEP-519 定义了表示“文件路径”的标准协议Path 对象实现了这个协议通过定义生成器函数来分块读取大文件可以节约内存使用 iter(callable,sentinel) 可以在一些特定场景简化代码难以编写测试的代码通常也是需要改进的代码让函数依赖“类文件对象”可以提升函数的适用面和可组合性原文作者piglei
http://www.zqtcl.cn/news/773172/

相关文章:

  • 西安做网站建设哪家好2345网址导航电脑版下载
  • 做暧暧小视频网站十大职业资格培训机构
  • 泰安网站建设优化营销策划是做什么
  • 做网站百度排前位网页设计实训报告2000字
  • 网站建设的活动方案房地产销售渠道拓客方案
  • 哈尔滨网站提升排名版式设计图片
  • 我的专业网站建设策划书网站logo教程
  • 百度 网站 移动端win10系统之家官网
  • h5商城网站建站成都网站建设全平台
  • xuzhou公司网站制作有什么手机网站
  • 网站建设 培训深圳网站建设制作品牌公司
  • 网站到期怎么续费网站运营优化推广
  • 一站式装修的利弊上海建设厅焊工证查询网站
  • 济宁做网站公司找融合深圳招聘一般在哪个网站
  • 重庆建网站推广公司个人网站需要建站群吗
  • 深圳网站建设吗个人博客网站制作代码
  • 化妆品网站模板网络营销的网站分类有哪些
  • 广州网站建设程序员培训wordpress 微信 抓取
  • 毕设给学校做网站个人店铺logo
  • 中国做w7的网站宿迁网站建设价位
  • 网站建设售后服务合同百度关键词排名点击器
  • 编辑网站用什么软件推广是什么
  • 北京模板开发建站做网站赚钱的点在哪里
  • 网站建设价格兴田德润i网址多少wordpress主题汉化是什么意思
  • 用最少的钱做网站根据域名查询网站名称
  • 网站开发答辩难点网站返回按钮设计
  • 鹤壁做网站优化建设银行理财产品网站
  • 电子商务类网站模板自学网站建设基本流程
  • 无锡网站制作的公司上海企业服务公司
  • 做h5小程序的网站搜索引擎营销案例