文件或名称

file-or-name的Python项目详细描述


PyPI VersionActions StatusCode style: blackDocumentation Status

透明地处理字符串或预打开的文件对象的输入参数。

Why?

当你写一个读写数据的函数时,你通常会得到这样的结果

defread_my_cool_file(file_name):withopen(file_name)asf:# Process file object f...

这有一些问题。

  1. It couples your data processing code and the opening of the file. This makes it harder to test. The thing you are actually testing is the code that processes the but with code like this you need to cooridnate the opening of the file during the test too. You need to either create fake data on dist of patch the open call.
  2. It can’t handle special files. If you have file in your special format but it uses ^{tt1}$ encoding instead of ^{tt2}$ how can you use that file? You can’t. The opening of the file is sealed inside the function meaning the user can’t easily change the behavior. Practices like this force file interaction to only be done in one way.

为了获得最大的灵活性和易测试性,您可能需要一个如下所示的函数

^{pr2}$

这很好,因为在测试时,您可以使用io.StringIO对象来动态创建测试数据。 您也可以打开不同编码的文件,然后将它们传入,以便像正常情况一样进行处理。这和 依赖注入方案,其中要处理的对象的创建在其自身进程之外完成 允许交换对象的确切格式。不过,可用性有一个倒退。这种处理文件的方式 对用户来说很麻烦。它将单个函数调用转换为多行调用。这个

data=read_my_cool_file("/path/to/my/imporant/data")

变成这样

withopen("/path/to/my/important/data")asf:data=read_my_cool_file(f)

像这样的函数也是与用户可能使用的许多其他函数的分歧。强制用户执行 对于您的库来说,不同的东西是减少采用率的一个可靠的方法。

我们需要一种方法来接受文件路径(字符串)和文件对象,而不必编写代码来检查它是什么 对于我们编写的每个io函数。

What?

输入file_or_name

file_or_name引入了一个装饰器@file_or_name,它为我们解决了这个问题。

通过用@file_or_name装饰函数,我们可以同时接受字符串和文件对象。我们上面的例子变成

@file_or_namedefread_my_cool_file(f):# Process file object f...

作为函数的编写者,我们可以编写一些函数,假设它们总是以file对象作为输入。这意味着我们 可以停止在函数中打开文件,这使它们更易于测试。

作为一个用户,我们可以传入一个文件的路径(作为一个字符串),使函数易于调用,或者我们可以传入一个 打开文件对象,它允许我们精确控制如何打开(控制编码等)。

Usage

当指定的参数包含字符串时,@file_or_name装饰器将自动打开和关闭文件 参数值。如果使用不带参数的decorator,它将以读取模式打开第一个参数作为文件。

fromfile_or_nameimportfile_or_name@file_or_namedefread_json(f):returnjson.load(f)

为了处理多个文件和文件写入,我们可以将关键字参数传递给表单中的decorator parameter=mode。这将使用此命令指定的模式打开由parameter的参数值指定的文件 关键字参数。

写入文件示例,当wf参数为字符串时,它将自动以写入模式打开:

fromfile_or_nameimportfile_or_name@file_or_name(wf='w')defwrite_json(data,wf):json.dumps(data,wf,indent=2)

读写示例,rfwf字符串的任何参数值都将在read中打开 模式和写入模式分别为:

fromfile_or_nameimportfile_or_name@file_or_name(rf='r',wf='w')defconvert_jsonl_to_yaml(rf,wf):forlineinrf:wf.write(yaml.dump(json.loads(line))+"\n")

文件或名称让您,库开发人员,编写函数,操作文件对象,使代码更干净等 可测试,同时允许用户使用简单的文件路径字符串参数与代码交互。它也会的 自动打开pathlib对象作为参数。

Shadow Paging

我经常有一些代码可以从带有生成器的文件中读取,这样我就可以一次处理大量的数据,而我没有 必须担心在内存中具体化整个文件。问题是当我想从文件中读取数据时,make 对其进行更改,然后写回同一个文件。你不能打开文件进行写入,因为那样会破坏 你正懒洋洋地用生成器从中读取的数据。一个常见的解决方案是将数据读入并保存在其中 内存,处理数据并将其全部写回。这就破坏了使用发电机的初衷 也意味着在写入数据时有可能出错会让你处于数据消失的状态。 这就是为什么我把影子页面介绍给这个库的原因。使用NamedTemporaryFile,您可以将此文件作为 正如您所希望的那样,当您关闭该文件时,它将自动用于以原子方式替换磁盘上的文件, 这意味着您不能因为在编写过程中出现错误而丢失数据,它允许您将数据写回原来的文件 用发电机来读取。

您可以通过在写入模式前面加上s

fromfile_or_nameimportfile_or_name@file_or_name(f='r',wf='sw')defreverse(f,wf):data=f.read()[::-1]ifrandom.random()<0.5:raiseValueErrorwf.write(data)

如果没有影子页,当您读入此数据并尝试将其写入时,ValueError之间的 当文件被打开以进行写入时以及实际写入时,可能会导致您丢失所有数据。如果错误 在使用卷影页时发生。原始读取数据将保持不变,如果未发生错误,则 数据将被反转。

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
内存Java正在运行。jar heapdump错误   java如何在安卓画布中弯曲文本区域?   java如何在Gdx 安卓游戏编程中获得矩形的真实触碰位置?   找不到java Spring MVC控制器   在Java中使用双重检查锁定单例扩展类   java在高效的时间和内存中动态执行insert(索引、数据)、delete(索引)、getAt(索引)操作。   java 安卓 Toast和视图帮助   java协议缓冲区:从文件中读取所有序列化消息   java如何在Jackson中为参数化接口类型执行通用自定义反序列化程序   与简单的空检查相比,使用(平面)映射的java优势是什么?   异步方法seam中的java Get contextparam   jar使用相同的java运行时运行另一个java程序   java访问Spring批处理中的作业参数   java给定字符串为空或null   在h2数据库1.4中找不到java类“org.h2.fulltext.FullTextLucene”。*不适用于Lucene Core 4*   java Spring Boot在使用@enableSync时不响应任何请求   java错误:在bash上找不到或加载主类pj2   “返回对象”和“返回(对象)”之间的Java差异   java Android开发:如何使用onKeyUp?