>백엔드 개발 >파이썬 튜토리얼 >Python 파일 읽기 작업에 대한 자세한 소개

Python 파일 읽기 작업에 대한 자세한 소개

不言
不言앞으로
2018-10-09 16:29:312790검색

이 기사는 Python 파일 읽기 작업에 대한 자세한 소개를 제공합니다. 이는 특정 참조 가치가 있으므로 도움이 될 수 있습니다.

파일 읽기 작업 단계

코끼리를 냉장고에 넣는 단계를 묻는 수수께끼가 있습니다. 대답은 매우 간단합니다. 냉장고를 열고, 코끼리를 밀어넣고, 냉장고를 닫으세요. 이는 문제를 해결하기 위한 아이디어입니다. 파일에 대한 작업은 동일합니다. 첫 번째 단계는 파일을 처리하는 것입니다(읽기 또는 쓰기). 어때요? 실제로는 매우 간단합니다. 파일 작업에 대해 자세히 이야기해 보겠습니다.

파일 열기

open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)

파일을 열려면 open() 함수를 사용해야 합니다. 초기에는 ()에 관련된 매개변수인 파일, 모드 세 가지만 알면 됩니다. , 인코딩

file

먼저 파일 이름, 유형은 경로를 포함한 문자열입니다. 열려는 파일이 현재 파일과 동일한 디렉터리에 있는 경우 경로(상대 경로)는 다음과 같습니다. 생략됩니다.

mode

파일이 열립니다. 모드, 형식은 다음과 같습니다: mode='mode', 여기에서 "mode="는 생략할 수 있습니다. 모드가 지정되지 않은 경우에는 모드를 직접 작성하면 됩니다. 기본은 r입니다. 특정 모드는 다음과 같습니다.
의사 명사 - 포인터가 여기에 도입되었습니다. Word에서 텍스트를 편집할 때 커서가 있다고 상상해 보세요. 포인터를 파일에 대한 모든 작업이 시작되는 커서로 생각할 수 있습니다.

r 
只读。文件的初始指针在文件的开头。这是默认模式。
rb
只读的二进制格式。文件的初始指针在文件的开头。
r+
读写。文件的初始指针在文件的开头。
rb+
读写的二进制格式。文件的初始指针在文件的开头。
w
只写。如果该文件已存在则打开文件,清空文件内容。如果该文件不存在,则创建新文件。
wb
只写的二进制格式。如果该文件已存在则打开文件,清空文件内容。如果该文件不存在,创建新文件。
w+
写读。如果该文件已存在则打开文件,清空文件内容。如果该文件不存在,创建新文件。
wb+
写读的二进制格式。如果该文件已存在则打开文件,清空文件内容。如果该文件不存在,创建新文件。
a
追加写。如果该文件存在,文件的初始指针在文件的结尾。新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
ab
追加写的二进制格式。如果该文件存在,文件的初始指针在文件的结尾。新的内容将会被写入到已有内容之后。如果该文件不存在,创建新文件进行写入。
a+
追加写读。如果该文件已存在,文件的初始指针在文件的结尾。文件打开时会是追加模式。如果该文件不存在,创建新文件用于读写。
ab+
追加写读的二进制格式。如果该文件已存在,文件的初始指针在文件的结尾。如果该文件不存在,创建新文件用于读写。

encoding

세 번째 매개변수는 파일의 인코딩입니다(비바이너리 형식으로 사용됨). 인코딩 설정은 열려는 파일의 인코딩과 일치해야 합니다. 그렇지 않으면 오류가 보고됩니다. 즉, 소스 파일에 어떤 인코딩이 사용됩니까? 쓰기를 위해서는 파일을 열 때 해당 인코딩을 사용해야 합니다.

파일 처리 중

실시할 작업은 "test"라는 파일을 여는 것입니다. 원래 파일 인코딩은 utf-8이고 열 때 gbk 인코딩을 사용했습니다.
문서에는 단 하나의 문장이 있습니다. 열 걸음에 한 사람을 죽이고 천 마일 동안 흔적을 남기지 마십시오.
코드는 다음과 같습니다.

file = open('test','r',encoding='gbk')
content = file.read()
print(content)
file.close()

open 함수에서 반환한 결과는 파일 객체이므로 변수를 사용하여 파일(파일)을 받아야 합니다.
file.read(), file.write, file.flush() 등과 같은 이 객체의 메소드입니다.
read()는 파일 객체의 메소드로, 그렇지 않은 경우 지정된 수의 문자를 읽는 것입니다. 지정하면 기본적으로 모든 내용을 읽습니다.
그러나 위 코드를 실행하면 오류가 보고됩니다. 다음은 오류 메시지입니다. 일반적인 아이디어는 gbk 인코딩을 디코딩할 수 없다는 것입니다(파일을 여는 과정은 실제로는 디코딩 프로세스)

    ---------------------------------------------------------------------------

    UnicodeDecodeError                        Traceback (most recent call last)

    <ipython-input-78-bb879f008680> in <module>()
          4 #这里说明以下,open函数返回的结果是一个文件对象,所以要用一个变量接收一下(file),这样我们就可以方便地使用这个
          5 #对象的方法了,比如file.read(),file.write,file.flush()等等
    ----> 6 content = file.read()#read()是文件对象的一个方法,作用是读取指定的字符数,如果未指定则默认读取所有内容
          7 print(content)
          8 file.close()

    UnicodeDecodeError: 'gbk' codec can't decode byte 0xad in position 4: illegal multibyte sequence

해결 방법은 매우 간단합니다. Linux 시스템의 기본 인코딩은 UTF-8이므로 인코딩을 생략할 수 있고, 우리는 단지 읽기를 원하기 때문에 인코딩 방법을 utf-8로 변경하면 됩니다. 해당 파일에는 모드가 r이고, 기본 모드가 r이므로 생략 가능하고 쓸 수 없습니다.
그러면 코드는 다음과 같습니다.

file = open('test')
content = file.read()
print(content)
file.close()
输出为:
十步杀一人,千里不留行

읽을 문자 수를 지정하는 read() 메소드에 숫자 매개변수를 추가할 수도 있습니다. 한자든 문자든 한 글자는 한 글자에 해당합니다. 문자나 한자여야 하며, 예시는 다음과 같습니다.

file = open('test')
content = file.read(3)
print(content)
file.close()
输出为:
十步杀

파일을 여는 방법은 마지막에 파일을 닫는 문을 작성해야 했기 때문에 더 번거롭습니다. 간단한 방법, 형식은 다음과 같습니다.

with open() as file_name:
    操作代码......

사용 이 방법의 장점은 파일을 닫는 명령문을 작성할 필요가 없다는 것입니다. 키워드와 마찬가지로 형식만 기억하면 됩니다.
다음으로 바이너리로 파일을 만듭니다. format

with open('二进制','wb') as file: 
    file.write('十步杀一人,千里不留行'.encode('utf8'))

파일을 여는 방식이 바이너리 형식으로 열리니까 그렇죠 그러면 파일을 쓸 때 바이너리 형식의 문자열을 써야 하는데 "Kill one person in ten"이라는 문자열의 바이너리 형식은 무엇인가요? 천 마일을 걸어도 흔적을 남기지 말라"고? 우리는 모르기 때문에 .encode(utf8)를 사용하여 이 문자열을 바이너리 형식으로 변환합니다. 실제로 다른 코드를 통해 이 문자열에 해당하는 바이너리 형식을 알 수 있습니다.

print('十步杀一人,千里不留行'.encode('utf8'))
输出的二进制格式(表现形式为16进制,为什么?因为二进制太长了啊!!!)为:
b'\xe5\x8d\x81\xe6\xad\xa5\xe6\x9d\x80\xe4\xb8\x80\xe4\xba\xba\xef\xbc\x8c\xe5\x8d\x83\xe9\x87\x8c\xe4\xb8\x8d\xe7\x95\x99\xe8\xa1\x8c'

在实际中我们当然不可能写这么长的东西,所以我们使用.encode('utf8')来转化。转化时我们使用了utf-8的编码方式。
在这里说明一下为什么要编码,想弄清楚这件事就要明白计算机的存储原理。
简单地讲,文件在计算机中都是以二进制格式存储的,对于计算机来讲只有两个数字有意义,那就是0和1,也就是二进制,而不同的0和1的组合代表不同的含义(编码不同),比如在gbk编码下一个汉字由两个字节表示,也就是16位二进制数(16个0和1的组合),而在utf-8编码下一个汉字由3个字节表示,也就是24位二进制数(24个0和1的组合),而我们现在要给计算机存储的就是0和1的组合,那么在读取文件或者转化字符串时,如果你不告诉计算机你使用的是哪种编码的话,计算机怎么可能知道这些0和1的组合代表什么含义呢?所以从计算机取出数据或者把普通字符串转化成二进制格式时你必须告诉计算机你使用的是什么编码方式。
在本例中使用utf-8编码,所以在字符串后面加上.encode(utf8)

那么为什么平时可以直接写入普通字符串呢?那是因为在用open()函数打开文件的时候就已经指定了编码方式。
形象地解释:open函数相当于打开了一种通道,平时打开时都是用某种编码的方式打开的,所以我们在写入内容时不必管它以什么编码进入通道的(因为在open函数里面就已经指定了编码方式)
而当open函数使用二进制格式打开时(就是带b的模式),这个通道就没有指定编码方式,通道里面只有二进制,所以此时往通道里面放入非二进制格式内容的话就需要指定一种编码方式。除非你直接在file.write()函数中直接写二进制,但是人类是不可能记住那么多二进制组合所代表的含义的。

然后我们来读取一下上面创建的名字为“二进制”的这个文件

with open('二进制','rb') as file:
    print('不指定解码方式时的结果:',file.read())

如果我们在读取时不指定解码方式,那么输出的结果就是下面这种人类无法理解的奇怪的东西(实际上它是用16进制表示的二进制)

不指定解码方式时的结果: b'\xe5\x8d\x81\xe6\xad\xa5\xe6\x9d\x80\xe4\xb8\x80\xe4\xba\xba\xef\xbc\x8c\xe5\x8d\x83\xe9\x87\x8c\xe4\xb8\x8d\xe7\x95\x99\xe8\xa1\x8c'

所以我们在读取时也要指定编码:

with open('二进制','rb') as file:
    content = file.read()
    print('指定解码方式后的结果:',content.decode('utf-8'))

指定解码方式后的结果: 十步杀一人,千里不留行

其他的在读取时可能用到的方法:

readline()读取一行,如果里面添加了参数n,则会读取n个字符(我觉得这是个bug,貌似没什么卵用)
readlines()读取所有内容,结果返回一个列表,元素由每一行组成。
tell()会输出当前指针的位置,注意,该位置是以字节来计算的,不是字符
seek()重新指定指针位置。

使用readlines()并不是一个好方法,因为是一次性将文件都读取到内存中,如果文件较大时则造成内存溢出,实际中使用下面的方法,系统会自动生成一个迭代器,用迭代的方法把需要的数据取出来。

with open('libai') as f:
    for i in f: #这里的i实际就是迭代后的每一行,用for循环的方式从文件对象中取出来,取一行读一行,节省内存
        print(i)
赵客缦胡缨,吴钩霜雪明。银鞍照白马,飒沓如流星。

十步杀一人,千里不留行。事了拂衣去,深藏身与名。

闲过信陵饮,脱剑膝前横。将炙啖朱亥,持觞劝侯嬴。

三杯吐然诺,五岳倒为轻。眼花耳热后,意气素霓生。

救赵挥金锤,邯郸先震惊。千秋二壮士,烜赫大梁城。  

纵死侠骨香,不惭世上英。谁能书阁下,白首太玄经。

关闭文件

如果用with open() 来打开文件的话就不用管关闭文件的操作了,因为Python已经帮你完成了这一步,否则必须在处理文件之后加上关闭文件的操作:file_name.close()


위 내용은 Python 파일 읽기 작업에 대한 자세한 소개의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 segmentfault.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제