文件
什么是文件
- 文件是数据存储的单位
- 文件通常用来长期存储数据
- 文件中的数据是以字节为单位进行顺序存储的
文件的操作流程
- 打开文件
- 读写文件
- 关闭文件
任何的操作系统,一个应用程序同时打开文件的数量有最大数限制
文本文件操作
文件操作方法
-
open(file, mode='rt')
用于打开一个文件,返回此文件对应的文件流对象,如果打开失败,则会触发OSError
错误-
file
要打开文件的路径 -
mode
文件打开模式
-
-
file.close()
关闭文件,释放系统资源 -
file.readline()
读取一行数据, 如果到达文件尾则返回空行 -
file.readlines(max_chars=-1)
返回每行字符串的列表,max_chars
为最大字符(或字节)数 -
file.read(size = -1)
从一个文件流中最多读取size
个字符 -
file.writelines(lines)
每行字符串的列表,参数是由字符串组成的序列 -
file.write(text)
写一个字符串到文件流中,返回写入的字符数,接收字符串参数,适用于一次性将全部内容写入文件 -
file.flush()
把写入文件对象的缓存内容写入到磁盘
总结
-
write()
接收字符串参数,适用于一次性将全部内容写入文件;而writelines()
接收参数是由字符串组成的序列,适用于将列表内容逐行写入文件 -
readline()
比较不优雅;read()
适合读取内容较少的情况,或者是需要一次性处理全部内容的情况;而readlines()
用的较多,比较灵活,因为for循环是一种迭代器,每次加载部分内容,既减少内存压力,又方便逐行对数据处理
try:
f = open('./info.txt')
print('文件打开成功')
f.close()
print('文件已关闭!')
except OSError:
print('文件打开失败!')
文件打开模式
-
r
以只读模式打开(缺省模式,必须保证文件存在) -
w
以只写模式打开。若文件存在,则删除原有文件内容;若不存在,则新建 -
a
以追加模式打开。若文件存在,则会追加到文件的末尾;若文件不存在,则新建 -
x
创建一个新文件, 并以写模式打开这个文件,如果文件存在则会产生FileExistsError
错误 -
b
用二进制模式打开 -
t
文本文件模式打开 (默认)
常见模式组合
-
r'或'rt
默认模式,文本读模式 -
w'或'wt
以文本写模式打开(打开前文件被清空) -
rb
以二进制读模式打开 -
ab
以二进制追加模式打开 -
wb
以二进制写模式打开(打开前文件被清空) -
r+
以文本读写模式打开,默认写的指针开始指在文件开头, 因此会覆写文件 -
w+
以文本读写模式打开(打开前文件被清空) -
a+
以文本读写模式打开(只能写在文件末尾) -
rb+
以二进制读写模式打开 -
wb+
以二进制读写模式打开(打开前被清空) -
ab+
以二进制读写模式打开 -
w+b
可以实现二进制随机读写,当打开文件时,文件内容将被清零 -
r+b
以二进制读和更新模式打开文件,打开文件时不会清空文件内容
文本文件的操作
默认文件中存储的都为字符数据,以行为单位进行分隔,在python内部统一用\n
作为换行进行分隔,对文本文件读写需要用字符串(str
)进行数据读取和写入
各种操作系统的换行符
- Linux换行符 :
\n
- Window换行符 :
\r\n
- 旧的Macintosh换行符:
\r
- 新的Mac Os 换行符 :
\n
文本文件的迭代读取
open()
函数返回来的文件流对象是可迭代对象
f = open('abc.txt')
# 每次取出一行,相当于line = f.readline()
for line in f:
print(line)
f.close()
标准输入输出文件
模块名: sys
-
sys.stdin
(默认为标准键盘输入设备)
ctrl + d 输入文件末尾标识 -
sys.stdout
(默认为屏幕终端) -
sys.stderr
(默认为屏幕终端)
二进制文件操作
对于二进制文件的读写通常需要用字节串(bytes
)进行操作
-
F.tell()
返回当前文件流的绝对位置 -
F.seek(offset, whence=0)
改变数据流的位置,返回新的绝对位置-
offset
偏移量
大于0
代表向文件末尾方向移动
小于0
代表向文件头方向移动 -
whenc
相对位置
0
代表人文件头开始
1
代表从当前读写位置开始偏移
2
代表从文件尾开始偏移
-
-
F.readable()
判断这个文件是否可读,可读返回True
,否则返回False
-
F.writable()
判断这个文件是否可写,可写返回True
,否则返回False
-
F.seekable()
返回这个文件对象是否支持随机定位 -
F.truncate(pos = None)
剪掉自pos
位置之后的数据,返回新的文件长度(字节为单位)
汉字编码
# 十个汉字占多少个字节
# GBK占20个字节 , UTF-8 占 30个字节
国标系列
-
GB18030
二字节或四字节编码 -
GBK
二字节编码 -
GB2312
二字节编码
(Windows 常用)
国际标准
-
UNICODE(2/4字节) <---> UTF-8 (1~6字节)
(Linux / Mac OS X / IOS / Android 常用)
python 编码(encode) 字符串
gb2312
gbk
gb18030
utf-8
ascii
编码注释
在源文件的第一行或第二行写入如下内容为编码注释
# -*- coding:gbk -*-
# 设置源文件编码为:gbk
with
语句
with 表达式1 [as 变量1], 表达式2 [as 变量2]:
语句块
- 使用于对资源进行访问的场合,确保使用过程中不管是否发生异常,都会执行必须的'清理'操作,并释放资源
- 能够用于
with
语句进行管理的对象必须是环境管理器
环境管理器
- 类内有
__enter__
和__exit__
实例方法的类被称为环境管理器 - 够用
with
语句管理的对象必须是环境管理器 -
__enter__
方法将在进入with语句时被调用,并返回由as
变量管理的对象 -
__exit__
将在离开with
语句时被调用,且可以用参数来判断在离开with
语句时是否有异常发生并做出相应的处理
class A:
def __enter__(self):
print("已进入with语句")
return self # 返回的对象将由 as绑定
def __exit__(self, exc_type, exc_val, exc_tb):
# exc_type 在没有异常时为None, 在出现异常时为异常类型
# exc_val 在没有异常时为None, 在出现异常绑定错误对象
# exc_tb 在没有异常时为None, 在出现异常时绑定traceback对象
print("已离开with语句")
对象的属性管理函数
-
getattr(obj, name[, default])
从一个对象得到对象的属性;getattr(x, 'y')
等同于x.y
; 当属性不存在时,如果给出default
参数,则返回default
,如果没有给出default
,则产生一个AttributeError
错误 -
hasattr(obj, name)
用给定的name
返回对象obj
是否有此属性,此种做法可以避免在getattr(obj, name)
时引发错误 -
setattr(obj, name, value)
给对象obj
的名为name
的属性设置相应的值value
,set(x, 'y', v)
等同于x.y = v
-
delattr(obj, name)
删除对象obj
中的name
属性,delattr(x, 'y')
等同于del x.y
class Dog:
pass
dog1 = Dog()
print(getattr(dog1,'color',None)) # None
dog1.color = 'white'
print(getattr(dog1,'color',None)) # white
print(hasattr(dog1,'kinds')) # False
print(hasattr(dog1,'color')) # True
setattr(dog1,'age',1)
print(getattr(dog1,'age',None)) # 1
delattr(dog1,'color')
print(getattr(dog1,'color',None)) # None
运算符重载
- 让自定义的类生成的对象(实例)能够使用运算符进行操作
- 让自定义的类的实例像内建对象一样运行运算符操作
- 让程序简洁易读
- 对自定义的对象,将运算符赋予新的运算规则
- 运算符重载不能改变运算符的优先级
算术运算符的重载
-
__add__(self, rhs)
self + rhs
加法 -
__sub__(self, rhs)
self - rhs
减法 -
__mul__(self, rhs)
self * rhs
乘法 -
__truediv__(self, rhs)
self / rhs
除法 -
__floordiv__(self, rhs)
self // rhs
地板除法 -
__mod__(self, rhs)
self % rhs
求余 -
__pow__(self, rhs)
self ** rhs
冪
反向算术运算符的重载
当左手边的类型为内建类型,右手边为自定义类型时,要实现运算必须用以下方法重载
-
__radd__(self, lhs)
lhs + self
加法 -
__rsub__(self, lhs)
lhs - self
减法 -
__rmul__(self, lhs)
lhs * self
乘法 -
__rtruediv__(self, lhs)
lhs / self
除法 -
__rfloordiv__(self, lhs)
lhs // self
地板除法 -
__rmod__(self, lhs)
lhs % self
求余 -
__rpow__(self, lhs)
lhs ** self
冪
复合赋值算术运算符的重载
-
__iadd__(self, rhs)
self += rhs
加法 -
__isub__(self, rhs)
self -= rhs
减法 -
__imul__(self, rhs)
self *= rhs
乘法 -
__itruediv__(self, rhs)
self /= rhs
除法 -
__ifloordiv__(self, rhs)
self //= rhs
地板除法 -
__imod__(self, rhs)
self %= rhs
求余 -
__ipow__(self, rhs)
self **= rhs
冪
class MyNumber:
def __init__(self,v):
self.data = v
def __repr__(self):
return 'MyNumber(%d)' % self.data
def __add__(self,other):
v = self.data + other.data
return MyNumber(v)
def __sub__(self,other):
v = self.data - other.data
return MyNumber(v)
n1 = MyNumber(100)
n2 = MyNumber(200)
n3 = n1 + n2 # 相当于 n3 = n1.__add__(n2)
print(n3)
n4 = n3 - n2 # 相当于 n4 = n3.__sub__(n2)
print(n4)
# ************************************************************
class MyList:
def __init__(self,iterator):
self.data = list(iterator)
def __repr__(self):
return 'MyList(%r)' % self.data
def __add__(self, other):
return MyList(self.data + other.data)
def __mul__(self, other):
return MyList(self.data * other)
def __rmul__(self, other):
return MyList(self.data * other)
def __iadd__(self, other):
self.data.extend(other.data)
return self
l1 = MyList([1,2,3])
l2 = MyList([4,5,6])
l3 = l1 + l2
print(l3)
l4 = l2 + l1
print(l4)
l5 = l1 * 2
print(l5)
l6 = 2 * l2
print(l6)
l7 = MyList([7,8,9])
l7 += l1
print(l7)
比较运算符的重载
比较运算符通常返回 True
或 False
-
__lt__(self, rhs)
self < rhs
小于 -
__le__(self, rhs)
self <= rhs
小于等于 -
__gt__(self, rhs)
self > rhs
大于 -
__ge__(self, rhs)
self >= rhs
大于等于 -
__eq__(self, rhs)
self == rhs
等于 -
__ne__(self, rhs)
self != rhs
不等于
位运算符重载
-
__invert__(self)
~ self
取反(一元运算符) -
__and__(self, rhs)
self & rhs
位与 -
__or__(self, rhs)
self | rhs
位或 -
__xor__(self, rhs)
self ^ rhs
位异或 -
__lshift__(self, rhs)
self << rhs
左移 -
__rshift__(self, rhs)
self >> rhs
右移
反向位运算符重载
-
__rand__(self, lhs)
lhs & self
位与 -
__ror__(self, lhs)
lhs | self
位或 -
__rxor__(self, lhs)
lhs ^ self
位异或 -
__rlshift__(self, lhs)
lhs << self
左移 -
__rrshift__(self, lhs)
lhs >> self
右移
复合赋值位运算符重载
-
__iand__(self, rhs)
self &= rhs
位与 -
__ior__(self, rhs)
self |= rhs
位或 -
__ixor__(self, rhs)
self ^= rhs
位异或 -
__ilshift__(self, rhs)
self <<= rhs
左移 -
__irshift__(self, rhs)
self >>= rhs
右移
一元运算符的重载
-
__neg__(self)
- self
负号 -
__pos__(self)
+ self
正号 -
__invert__(self)
~ self
取反
in / not in
运算符的重载
def __contains__(self, e) # e in self 成员运算
pass
索引和切片运算符的重载
让自定义的类型的对象能够支持索引和切片操作
-
__getitem__(self, i)
x = self[i]
索引/切片取值 -
__setitem__(self, i, v)
self[i] = v
索引/切片赋值 -
__delitem__(self, i)
del self[i] del
语句删除索引等
slice
构造函数
- 用于创建一个
Slice
切片对象,此对象存储一个切片的起始值,终止值和步长信息 -
slice(start, stop=None, step=None)
创建一个切片对象-
s.start
切片起始值,默认为None
-
s.stop
切片终止值,默认为None
-
s.step
切片步长,默认为None
-