Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/340.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 作为函数参数的文件名与文件对象_Python_Unit Testing_Python 3.x_Arguments_Software Design - Fatal编程技术网

Python 作为函数参数的文件名与文件对象

Python 作为函数参数的文件名与文件对象,python,unit-testing,python-3.x,arguments,software-design,Python,Unit Testing,Python 3.x,Arguments,Software Design,如果一个函数以文本文件的名称作为输入,我可以将其重构为一个file对象(我称之为“stream”;还有更好的词吗?)。优点显而易见-将流作为参数的函数是: 编写单元测试要容易得多,因为我不需要为测试创建临时文件 更灵活,因为我可以在变量中已经包含文件内容的情况下使用它 溪流有什么缺点吗?或者我应该始终将函数从文件名参数重构为流参数(当然,假设文件仅为文本)?python标准库中有许多函数同时接受这两种参数——字符串是文件名或打开的文件对象(我假设这就是您所指的“流”)。创建一个装饰器并不难,

如果一个函数以文本文件的名称作为输入,我可以将其重构为一个file对象(我称之为“stream”;还有更好的词吗?)。优点显而易见-将流作为参数的函数是:

  • 编写单元测试要容易得多,因为我不需要为测试创建临时文件
  • 更灵活,因为我可以在变量中已经包含文件内容的情况下使用它

溪流有什么缺点吗?或者我应该始终将函数从文件名参数重构为流参数(当然,假设文件仅为文本)?

python标准库中有许多函数同时接受这两种参数——字符串是文件名或打开的文件对象(我假设这就是您所指的“流”)。创建一个装饰器并不难,您可以使用它使您的函数接受其中任何一个


使用“流”的一个严重缺点是,将它传递给函数,然后函数从中读取——有效地改变了它的状态。根据您的程序,如果有必要,恢复该状态可能会很混乱。(例如,您可能需要在代码中乱扔
f.tell()
,然后
f.seek()

。。。以下是
xml.etree.ElementTree
模块如何实现该功能:

def parse(self, source, parser=None):
    close_source = False
    if not hasattr(source, "read"):
        source = open(source, "rb")
        close_source = True
    ...
由于filename是一个字符串,因此它没有
read()
方法(此处选中该名称的任何属性);但是,打开的文件有它。这四行代码使其余代码变得通用。唯一复杂的是,您必须记住是否关闭文件对象(此处命名为
source
)。如果它是
打开的
内部,则必须将其关闭。否则,不得将其关闭


实际上,文件与sream略有不同。流可能是无限的,而文件通常不是无限的(除非某些设备被映射为文件)。处理时的重要区别在于,您永远无法将流一次读入内存。您必须按块处理它。

是的,当我说“流”时,我的意思是“打开文件对象”。难道不可能编写一个保存和恢复流状态的装饰程序吗?难道没有一种方法可以创建一个廉价的流副本,这样副本就拥有自己的“指针”,而原始流的“指针”就保持不变吗?这比“保存/还原状态”方法更简洁。因此,“文件名”与“文件对象”感觉有点像“iterable”与“迭代器”。@max--我想这是类似的。我不能代表其他人说话,但我通常希望函数更改流的状态。例如,我希望我的(假设的)“parse_header”函数将文件指针保留在头的末尾,这样下面的“read_item”就可以从文件中的适当点开始读取。我正在stdlib中寻找关于这一点的参考实现。谢谢你的片段,它真的节省了时间。如果可以的话,我会给另外一个+1作为块的警告。