返回

文章详情

减少假设,优化您的代码

Hacker News2026年7月5日 07:22

优雅的脚本 我们都写过这些脚本,它们完美地结合在一起,易于阅读,但它们假设了一切都是顺利的。这个世界可以是一个快乐的地方,但它也是深陷缺陷和不完美之中,为了让您的代码在这样的世界中正常运行,甚至增加价值……它必须处理这些不完美。 我们的优雅、世俗的例子 我们的脚本将接受一个 ID 作为参数。它会在 setup.json 中找到一个 API token,并请求从远程服务器下载 PDF。下载文件的名称由服务器决定。很简单,但有点现实的杂乱,不过嘿——我们是程序员,这就是我们所做的,我们对此充满热情,对吧 :) ……对吧 :I(想想所有的 vibeco…) Python 版本 Python 是编程的通用语言。让我们开始吧! import sys , json , requests , re from requests.auth import HTTPBasicAuth id = int ( sys . argv [ 1 ]) with open ( 'setup.json' ) as f : setup = json . load ( f ) url = f "https://www.example.com/pdf-api?id= { id } " resp = requests . get ( url , auth = HTTPBasicAuth ( setup [ 'token' ], 'x' )) pattern = re . compile ( r "filename\\*?=[f']?(.*?)[']?(?:;?$)" ) content_disp = resp . headers [ 'Content-Disposition' ] filename = pattern . search ( content_disp ) . group ( 1 ) with open ( filename , 'wb' ) as f : f . write ( resp . content ) 这是一个完美的小脚本。每个代码块只完成一项工作,每个都只有几行,几乎没有多余的结构或样板代码——我喜欢它。 Rye 版本 由于这是一个 Rye 语言的博客,我们也会用 Rye 来编写这段代码 :) rye .Args? .load .first :id Load %setup.rye | context :setup re : regexp "filename\\*?=[f']?(.*?)[']?(?:;?$)" format id https ://www.example.com/pdf-api?id=%d | Request 'GET "" | Basic-auth! setup/token "x" | Call :resp | Header? "Content-Disposition" | Submatch?* re | file .Create | Copy* Reader resp 好吧,有点不同,但还是相似。我们假设了什么?脚本总是获取一个整数参数设置文件存在且内容正确HTTP 请求从不失败Content-Disposition 头部总是存在并带有文件名我们总是可以创建一个新文件 正如尤金·路易斯·福特斯沃思所说——这些都是很多……假设 :( 增加基本验证(步骤 2) 我可以像尤金的淡化版本:“用户输入是许多问题的源头”。没有用户输入,就没有问题——但我们需要用户。所以让我们验证这些输入。 Python 版本 我们现在将: 检查参数的数量 检查 ID 是否为整数 检查设置是否定义了 token 值 import sys , json , requests , re from requests.auth import HTTPBasicAuth if len ( sys . argv ) != 2 : raise ValueError ( "脚本参数 id - 预期确切为一个整数" ) try : id = int ( sys . argv [ 1 ]) except ValueError : raise ValueError ( "脚本参数 id - 必须是一个整数" ) with open ( 'setup.json' ) as f : setup = json . load ( f ) if 'token' not in setup or not isinstance ( setup [ 'token' ], str ): raise ValueError ( "加载设置 - token 字段需要作为字符串" ) url = f "https://www.example.com/pdf-api?id= { id } " resp = requests . get ( url , auth = HTTPBasicAuth ( setup [ 'token' ], 'x' )) pattern = re . compile ( r "filename\\*?=[f']?(.*?)[']?(?:;?$)" ) content_disp = resp . headers [ 'Content-Disposition' ] filename = pattern . search ( content_disp ) . group ( 1 ) with open ( filename , 'wb' ) as f : f . write ( resp . content ) 我们增加了这些检查,如果你问我(我对此有所偏爱),优雅、可读的脚本已经不复存在。这是我厌恶 try/catch 方法的原因之一。它增加了打断代码流的结构。 Rye 版本 rye .Args? .validate { <one> integer } | check "脚本参数 id" | first :id Load %setup.rye | context | validate { token : required string } | check "设置文件" :setup re : regexp "filename\\*?=[f']?(.*?)[']?(?:;?$)" format id https ://www.example.com/pdf-api?id=%d | Request 'GET "" | Basic-auth! setup/token "x" | Call :resp | Header? "Content-Disposition" | Submatch?* re | file .Create | Copy* resp .defer \ 'Close | Copy* resp .Reader .defer \ 'Close 我们使用了参数和配置的验证方言。并且使用 .defer\ 'Close 来确保资源(文件写入器和 HTTP 流读取器——顺便说一下,没有复制到内存)被清理。脚本变得更复杂了一些,但它的结构和流并没有改变。 完全错误处理(步骤 3) 现在让我们处理所有的故障,并在失败时给用户提供有用的反馈。我们的最初优雅的脚本变成了这样…… :o Python 版本 我们现在还检查: setup.json 是否存在我们能否解析 setup.json 的 JSON HTTP 请求是否成功如果没有 Content-Disposition,我们提供默认的文件名我们能否创建新文件我们能否将 PDF 写入其中 import sys , json , requests , re from requests.auth import HTTPBasicAuth # 验证参数 if len ( sys . argv ) != 2 : print ( "错误:脚本参数 id - 预期确切为一个整数" ) sys . exit ( 1 ) try : id = int ( sys . argv [ 1 ]) except ValueError : print

赞助内容

NordVPN Next-gen Antivirus

本站免费、广告极少。如果觉得有帮助,可以请我们喝杯咖啡 —— 任何金额都对持续运营有实际帮助。

请我喝杯咖啡