python学习 11 文件操作

一. 文件概述

1.什么是文件

计算机文件是一个存储在存储器上的数据序列,可以包含任意数据内容。
概念上,文件是数据的集合和抽象。
用文件形式组织和表达数据更有效也更为灵活。
文件包括两种类型:文本文件和二进制文件
文件本质上都是存储在存储器上的二进制数据。
使用 HexEditor 可以以 16 进制的方式打开任何文件
在这里插入图片描述
那么怎么区分二进制文件和文本文件呢?
遵循统一的字符编码的文件我们称为文本文件,在打开时,计算机会根据字符编码解析成编码表上对应的字符,可以简单理解为,能用记事本正常打开(打开之后不乱码能看懂内容)这种就是文本文件。
二进制文件和文本文件本质上没有区别,只是没有统一的编码,需要根据特定的程序进行解析和执行,二进制文件,是不同的文件有不同的编码,所以不同的文件需要不同的软件去打开去运行。
无论是文本文件还是二进制文件都可以用’文本文件方式’和二进制文件方式打开,打开后的操作不同。

2 .信息量

计算机只能识别 0 和 1,也就是我们常说的二进制,任何信息也是通过0和1来表达,信息的最小单位叫bit,它可以表达一位二进制数,也就是可以表达两种情况。0或1 ,8bit叫做一个 Byte(字节),一个字节可以表示2的八次方种情况,即256种,计算机中的存储单元,例如内存,硬盘等都是使用Byte作为最小单位,接下来的单位大家估计耳熟能详。

  • 1024 Byte = 1 KB
  • 1024 KB = 1MB
  • 1024MB = 1GB
  • 1024 GB = 1TB

信息量的最小单位是bit,存储单元的最小单位是byte(字节),衡量一个数据的大小要看这个数据占据的字节数

所有的信息都是转换成二进制数据存储在电脑中,再按照信息占据的字节数来计算衡量大小
例如0-255 的整数使用一个字节就可以表示和存储。
整数天然的可以转换成二进制信息,其他的信息需要通过各种方法进行转换

3.字符编码

计算机底层只能表示二进制信息,不能直接表示文字,计算机显示给我们看的文字可以看作是很小的一张张字符的图片,但如果文字都以图片进行存储和传输,图片体积非常大,从而效率会变得很低。
所以计算机科学家将这些单个字符图片放到一个文件中,这个文件就是字体文件,再给每个字符一个编号,存储传输时就用字符编号,这个编号就是字符编码(简单这么理解)
文本文件存储的就是每个字符的编号,计算机在打开文本文件时,会根据指定的编码,去编码表中查询一个一个的字符,再渲染给用户。

3.1 ascii码

标准的ascii码包含26个大小写字母,阿拉伯数字0-9以及以及常用的标点符号等128个字符,通过计算使用7位二进制就可以表示,扩充后调整为8位,编码详情如下:
在这里插入图片描述
例如在ascii码中,字符A的编码为65,当在文件中存入字符A时,实际计算机存储的编码是65,打开文件时,计算机会根据编码去字体文件中找到字符A
ascii码是全球统一的,一个字符是一个字节。

3.2 gb2312

计算机最早是欧洲发明的
当计算机发展到欧洲以外的其他国家和地区后,为了能够使用自己国家的文字,各国发明了自己国家的字符编码,我国在1980年发布了gb2312,gb2312是一个简体中文字符集,由6763个常用汉字和682个全角非汉字字符组成,使用一个字节不足以表示gb2312,因此,在gb2312中使用两个字节表示一个汉字。

'中'.encode('gb2312')

b’\xd6\xd0’

3.3 gbk

GB2312 的出现,基本满足了汉字的计算机处理需要,但对于人名、古汉语等方面出现的罕用字,GB 2312 不能处理,这导致了后来 GBK 及 GB18030 汉字字符集的出现。

GBK 即汉字内码扩展规范,K 为扩展的汉语拼音中“扩”字的声母。GBK 编码标准兼容 GB2312,共收录汉字 21003 个、符号 883 个,并提供 1894 个造字码位,简、繁体字融于一库。

gbk 也是使用两个字节表示一个汉字。

'中'.encode('gbk')

b’\xd6\xd0’

'囙'.encode('gb2312')

UnicodeEncodeError Traceback (most recent call last)

in
----> 1 ‘囙’.encode(‘gb2312’)

UnicodeEncodeError: ‘gb2312’ codec can’t encode character ‘\u56d9’ in position 0: illegal multibyte sequence

‘囙’.encode(‘gbk’)

3.4 unicode

世界上存在着多种编码方式,同一个编码值,在不同的编码体系里代表着不同的字。要想打开一个文本文件,不但要知道它的编码方式,还要安装有对应编码表,否则就可能无法读取或出现乱码。

我上大学时玩电脑游戏最大的问题就是乱码。

以日文的编码方式创建一个文本文件写入 やめて,然后用记事本打开会显示如下:

在这里插入图片描述
这个问题促使了 unicode 码的诞生。

unicode 将世界上所有的符号都纳入其中,无论是英文、日文、还是中文等,大家都使用这个编码表,就不会出现编码不匹配现象。每个符号对应一个唯一的编码,乱码问题就不存在了。

Unicode 固然统一了编码方式,但是它的效率不高,比如 UCS-4(Unicode 的标准之一)规定用 4 个字节存储一个符号,那么每个英文字母前都必然有三个字节是 0,这对存储和传输来说都很耗资源。

将之前写有 abc123±*\ 的文件用记事本另存为 unicode 会发现文件的体积大了一倍。(本来应该是 4 倍,windows 做了优化)

在这里插入图片描述
在这里插入图片描述

3.5 utf - 8

为了提高 Unicode 的编码效率,于是就出现了 UTF-8 编码。UTF-8 可以根据不同的符号自动选择编码的长短。比如英文字母可以只用 1 个字节就够了。"汉"字的 Unicode 编码是 U+00006C49,然后把 U+00006C49 通过 UTF-8 编码器进行编码,最后输出的 UTF-8 编码是 E6B189。utf-8 中汉字使用 3 个字节存储。

'a'.encode('utf-8')

b’a’

'中'.encode('utf-8')

b’\xe4\xb8\xad’
注意为了统一 python3 在内存中所有的字符都采用 unicode。
总结:

  • ascii码 一个字节表示一个字符
  • gbk 两个字节表示一个汉字
  • unicode 四个字节表示一个字符
  • utf - 8 一个字节表示一个英文字母,三个字节表示一个汉字,

后三个编码都兼容 ascii码

4. 字节类型

python中使用bytes来表示二进制信息,它是由单个字节构成的不可变序列,bytes字面量的语法与字符串字面值大致相同,只是添加了一个b的前缀,bytes字面量中只允许ASCII字符,任何超过127的二进制值使用十六进制来表示。

4.1 编码与解码

编码 : 字符串----> 字节 ( 二进制)
解码 : 字节----->字符串
字符方法encode可以将字符转换为对应的编码的bytes对象

s = '中国'   #  --- gbk  编码  
res = s.encode('gbk') # ascii, gb2312, gbk, utf-8, unicode_escape
print(res)  # b'\xd6\xd0\xb9\xfa'
#  b'\xd6\xd0\xb9\xfa' -> 中国  解码
res = b'\xd6\xd0\xb9\xfa'.decode('gbk')
 # 解码时要给出相应的编码,如果给出的是不对的编码类型会报错。
print(res)   # 中国

注意:并不是所有的数据都可以进行解码的,只有是本身的二进制数据就是用字符编码去编码的字符,才能去解码。

二. python操作文件

python提供内置函数open()实现对文件的操作。
python对文本文件和二进制文件都采用统一的操作步骤,和把大象放冰箱里一样分三步,‘打开-操作-关闭’.

2.1 open函数

open(file, mode=‘r’, encoding=None)
打开文件并返回对应的file object. 如果文件不能打开,则触发OSError

  • file 包含文件名的字符串,是一个路径,可以是绝对路径,也可以是相对路径
  • mode 模式 一个可选字符串,用于指定打开文件的模式,默认值r表示文本读
  • encoding 文本模式下指定文件的字符编码

mode 的取值
在这里插入图片描述
文件打开的模式:
r(read):只读模式,文件不存在会报错,找不到文件。
a(append):追加写入(不支持读取),不存在则创建一个。
w(write):清空文件中原有的内容,写入(不支持读取),文件不存在则创建一个。
rb: 以二进制模式打开文件,只读模式
ab:以二进制模式打开文件,追加写入(不支持读取)文件不存在则创建一个
wb:清空文件中原有的内容,以二进制模式打开文件,写入(不支持读取),文件不存在则创建一个
可以和上面几个mode进行组合的字符
在这里插入图片描述

2.读文本文件

在当前目录下创建一个名为 test.txt的文本文件,(注意编码方式),文件中写入下面的内容:

静夜思
床前明月光,疑是地上霜。
举头望明月,低头思故乡。
2.1读文本文件 – 基本操作步骤

要求: 读取test.txt中的内容

# 打开 mode=rt,t可以省略
fb = open('test.txt', 'r', encoding='utf-8') # 会返回一个文件对象,通过这个对象你才能去操作。
# 读取
content = fb.read()   # read()读取文件里面的内容
# 关闭文件
fb.close()
print(content,type(content))

静夜思
床前明月光,疑是地上霜。
举头望明月,低头思故乡。 <class ‘str’>

上面这种操作经常会忘记关闭文件句柄,造成资源浪费,所以处理文件是往往使用 with 语句进行上下文管理。

2.2 读文本文件 – with 上下文管理

自动关闭文件,自动释放资源,极其常用。

with open('test.txt', 'r', encoding='utf-8') as fb:   # 固定写法
    content = fb.read()  # 从文件 fb 中把所有文件全部读取出来
    print(content, type(content))

with 语句结束之后,会自动调用fb上的close方法
大多数情况下我们会这样去用,避免我们没有及时释放文件句柄
静夜思
床前明月光,疑是地上霜。
举头望明月,低头思故乡。 <class ‘str’>
with 语句执行完毕会自动关闭文件句柄。

2.3 相对路径与绝对路径

进行文件处理时经常会碰到相对路径和绝对路径的问题。

绝对路径好理解,它指定了文件在电脑中的具体位置,以 windows 电脑为例:

d:\lemon\课件\python入门.md

相对路径一般是指相对当前脚本的路径,比如上面的案例中的 test.txt 因为和当前脚本在同一个文件夹下,所以可以直接使用 test.txt 作为文件名来操作。

也可显式的表达当前路径 ./test.txt,./ 表示当前目录。

../ 表示上级目录,同理 ../../表示上上级目录,依此类推。

那什么时候使用相对路径,什么时候使用绝对路径呢。

在项目的内部,有文件依赖,文件的相对位置固定,所以一般使用相对路径,便于项目的移植
如果需要读取操作系统中固定位置的系统文件一般使用绝对路径。
当前目录:例如 aaa/text.txt

  • 相对路径:参照标准 是当前脚本 .表示当前目录,两个点表示上级目录
    当前目录下的a.txt文件: ./a.txt 一般情况下./可以省略,可以写成a.txt
    上级目录下的a.txt文件 ../a.txt这个就不能省略了 ../../../some.txt
  • 绝对路径:参照标准是系统的根目录,一般对系统文件有引用的时候使用。
    linux : /temp/xxx
    windows: c\

在真实项目中,一般会动态生成绝对路径。
上面也可以写成绝对路径

with open(r'E:\代码\Python笔记\test.txt', 'r', encoding='utf-8') as fb:
    content = fb.read()
    print(content, type(content))

因为在windows 中路径是反斜杠,所以为了让它不转义,我们需要在字符串前面加一个 r

2.4 读文本文件 - 按行读取

文本对象,文件句柄,open函数返回的对象,提供了一系列的方法,可以按行读取

  • readline

从文件中读取一行,当读到最后一行后,这个方法会返回空字符串
每执行一遍返回一行

with open('test.txt', 'r', encoding='utf-8') as fb:
    print(fb.readline())
    print(fb.readline())
    print(fb.readline())
    print(fb.readline())

静夜思

床前明月光,疑是地上霜。

举头望明月,低头思故乡

后面不管再读多少行都是返回空
判断readline 是否返回了空字符串,当读到最后一行后,这个方法会返回空字符串

with open('test.txt', 'r', encoding='utf-8') as fb:
	index = 0
	while True:
		index += 1
		res = fb.readline()
		if res == '':
			break
		print(index,res)
  • readlines(很少用)
    以列表的形式返回文件中所有的行
with open('test.txt', 'r', encoding='utf-8') as fb:
    content = fb.readlines()
    print(content)

[‘静夜思\n’, ‘床前明月光,疑是地上霜。\n’, ‘举头望明月,低头思故乡。\n’, ‘\n’, ‘\n’]

  • 迭代文件对象(最常用)

以迭代的方式读取文件的每一行

# 5星推荐
with open('test.txt', 'r', encoding='utf-8') as fb:
    for line in fb:
        print(line,end='')

静夜思

床前明月光,疑是地上霜。

举头望明月,低头思故乡。

2.5 以二进制方式读取文件

以二进制方式读就没必要指定它的编码,它是什么就会读什么。

with open('text.txt','rb') as fb:
	content = fb.read()
	print(content)

3.写文本文件

多数情况下,我们操作的是文本文件

3.1 清除写 - w

mode = ‘w’ 表示清除写,清空写,当以w的方式打开一个文件的时候,首先清空然后再写,所以谨慎使用
文件不存在则创建
如果存在则首先清空,然后再写,所以谨慎使用。
文件对象有.write()方法,往文件里写入内容,文本模式传字符串

with open('text.txt','w',encoding = 'utf-8')as fb:  # 这行代码执行后,目标文件的内容就清空了
	fb.write('静夜思\n')
	fb.write('窗前明月光,疑是地上霜\n')
	fb.write('举头望明月,低头思故乡\n')
# fb 就是普通的变量,可以用其他任意内容代替。
3.2 追加写 - a

mode = ‘a’ 表示追加,写入的内容会追加到文件的最后,如果文件不存在,则创建。

with open('text.txt','a',encoding='utf-8) as fb:
	fb.write('123')

不断运行会不断追加
如果不存在的则会创建
会默认追加到最后

3.2 排他写 - x

mode = ‘x’ 表示排他写,如果文件不存在创建,存在则报错。
只有不存在的时候才会正常运行

with open('bbb','x','encoding='utf-8') as f:
	f.write('321')

4 . 读写二进制文件-复制文件

复制一个图片(小文件可以这样写)

# 1.读取原来的图片内容
with open('test.jpg','rb')as fb:
	content = fb.read()
# 2.创建一个新的文件
# 3.把读取的图片内容写入这个新的文件
with open('test2.jpg','wb') as fb:
	fb.write(content)
注意:在python中局部变量只有函数

读写文件

有时候需要能够同时读写文件,在模式后面加上 + 号 即可给读模式添加写,给写模式添加读

with open('test.txt', 'r+', encoding='utf-8') as f:
    # 读文件
    print(f.read())
    f.write('草\n离离原上草,一岁一枯荣; \n野火烧不净, 春风吹又生! \n')

5.python 解析csv文件

什么是csv文件:逗号分隔值,每一行代表一行数据,每一列代表一列数据
comma c逗号 seperate分隔 value值

使用嵌套列表来表示csv文件
[
['name','age','height'],
[心蓝,18,170],
[小白,19,185],
[开普勒,20,160],
[jj,17,155],
]
with open('test.csv', 'r', encoding='utf-8') as fb:
    data = []
    for line in fb:
        line = line.strip().split(',')
        data.append(line)
print(data[2])

# 把 data 写到csv 文件中
with open('test1.csv', 'w', encoding='gbk') as fb:
    for line in data:
        fb.write(','.join(line)+'\n')

4.路径处理

python里面的os模块有许多方法让我们通过代码实现创建,删除和更改目录,(是python和操作系统交互的模块)具体罗列如下:
熟记: os.path.dirname 和 os.path.join
在这里插入图片描述
在这里插入图片描述
dirname 获取文件或目录的上级目录路径
在这里插入图片描述
join方法:拼接路径 把两个路径拼起来。
拼接的时候会自动加/,不需要去手动写。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
sys模块和python解释器交互,os模块和操作系统交互

模块与包

1.模块和包的定义
模块(Module):模块是一个python文件,以.py结尾,包含了python对象定义和python语句
包(Package): python中的包就是一个包含一个__init__.py文件的目录(文件夹),在Python文件里面只要有一个__init__.py的文件,那么这个文件夹就是一个python的包。

什么时候创建文件夹,什么时候创建包
如果里面要写python代码,要定义成Python的包。
如果不是放python文件的就可以创建普通的文件夹。
2.模块和包的导入

  • .模块让你能够有逻辑地组织你的python代码段
  • 把相关的功能代码写到一个模块里能让你的代码更好用,更易懂
  • 模块能定义函数,类和变量,模块里也能包含可执行的代码。

在这里插入图片描述
模块的导入
import 模块名
from 包.下级的包 import 模块名(就是文件名去掉.py)

导入模块里面的变量或者函数
form 包.模块 import 变量/函数/类
除了顶级目录,一层一层地拨开你的心
在这里插入图片描述
这个条件,只有在直接运行这个文件的时候才会成立。
下面这个条件只有直接运行这个文件才会成立(模块导入时,这个条件不会成立)
if name ==‘main’:
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值