加深对Python read()函数的理解

时间:2019-01-22 12:01:13

标签: python python-3.x

我有以下Python 3脚本:

from sys import argv

script, filename = argv

txt = open(filename)

print(f"Here's your file {filename}:")

print(txt.read())

当我们使用内置函数open()时,我们打开文件并返回相应的文件对象。

我知道read()不是内置函数,而是文件对象的方法。

如Python文档中有关文件对象https://docs.python.org/3/glossary.html#term-file-object所述:

  

文件对象实际上分为三类:原始二进制文件,   缓冲的二进制文件和文本文件。它们的接口在   io模块。

我真的很难理解一些关键领域。

1)如何知道原始二进制文件,缓冲二进制文件和文本文件将使用哪种文件对象类型?在此示例中,我使用的是简单的.txt文件,因此我假设文件对象是文本文件。

2)使用io模块时,如何知道正在调用哪种特定的read()方法?它属于哪个类,因为多个类都有可用的read方法

请尽量简化答案,因为我是Python新手。我只是不太了解io模块的文档。从第3步开始,我很快迷失了方向,需要通过简单的步骤向我进行解释。

我正在尽力了解浏览文档的逻辑步骤,因此请适当地修改这些步骤。

我的理解如下:

  1. 我们调用内置的open()函数
  2. 这将打开一个文件并返回一个相应的文件对象。
  3. 然后,我们使用io模块来处理文件对象。
  4. 确定我们正在使用的文件对象的类别,在这种情况下,我认为它是文本I / O
  5. 文本IO声明'文本流API在以下文档的文档中有详细说明 TextIOBase。'
  6. 使用的类io.TextIOBase具有多种可用的方法,例如read()

4 个答案:

答案 0 :(得分:2)

任何文件对象之间都有某些相同的地方,您可以在class hierarchy中看到它们。所有文件对象都以IOBase作为其基类,基类定义了所有文件对象共有的东西。然后,它专门研究RawIOBaseBufferedIOBaseTextIOBase类,然后进一步研究FileIOBytesIO等。这是典型的OOP类层次结构。

它们的共同点是它们都定义了read方法。该方法的作用在细节上稍有不同,但是总体功能是相同的:它从基础数据中读取任何内容并返回该数据。那是典型的OOP抽象/封装/多态性:您不需要关心它是如何做的或究竟是做什么的,您只需要知道调用.read()即可获取数据。

您可以分别实例化这些类,但是通常使用open来简化该潜在的复杂任务。 open根据您的确切要求决定返回哪个班级:

  

Text I/O

     

文本I / O期望并产生str个对象。这意味着无论何时   后备存储本机由字节组成(例如   文件),对数据的编码和解码也是透明的   平台特定的换行符的可选翻译。

     

创建文本流的最简单方法是使用open(),(可选)   指定编码:

f = open("myfile.txt", "r", encoding="utf-8")
  

Binary I/O

     

二进制I / O(也称为缓冲I / O)期望使用bytes类对象,并且   产生bytes个对象。没有编码,解码或换行符   进行翻译。 [...]

     

创建二进制流的最简单方法是使用open()'b'   在mode字符串中:

f = open("myfile.jpg", "rb")
  

Raw I/O

     

原始I / O(也称为无缓冲I / O)通常用作低级   二进制和文本流的构建块;它很少有用   直接从用户代码操纵原始流。不过,您可以   通过使用buffering以二进制模式打开文件来创建原始流   禁用:

f = open("myfile.jpg", "rb", buffering=0)

答案 1 :(得分:0)

这与如何打开文件有关。

如果调用open(path),则将打开path作为文本文件对象。如果调用open(path, 'rb'),则将作为缓冲二进制文件打开。如果调用open(path, 'rb', buffering=0),则将以未缓冲的二进制文件形式打开。就这么简单=)

有关更多信息,请参阅https://docs.python.org/3/library/io.html

答案 2 :(得分:0)

  

我怎么知道原始二进制文件,缓冲二进制文件和文本文件将使用哪种文件对象类型?在此示例中,我使用的是简单的.txt文件,因此我假设文件对象是文本文件。

您没有。但是,有一些方法可以识别/猜测文件的内容类型,这与Linux的file命令非常相似。例如,看看python-magic包:

import magic
m = magic.Magic(mime=True)    
print(m.from_file(filename))

这将为您提供文件的MIME type,例如application/json,然后您便知道是将其读取为文本文件还是二进制文件。

是否要读取已缓冲的文本或二进制文件,取决于打开方式,另请参见io模块。

其他答案提供了有关IO的更多详细信息,因此我不在这里讨论……

答案 3 :(得分:0)

  

在此示例中,我使用的是简单的.txt文件,因此我认为文件对象将是文本文件。”

这完全无关。

扩展名仅是一个命名约定。它与有效内容完全无关-从纯技术POV总是由字节组成(区别在于字节的解释方式)-与IO类{{1} }将使用cf deceze的完整且出色的答案。