Python-Task7 文件与文件系统

Python-第七天 文件与文件系统

学习内容

廖雪峰老师python教程https://www.liaoxuefeng.com/wiki/1016959663602400

小甲鱼python教程


文件读写

文件读写由操作系统提供,所以不允许普通程序直接操作磁盘硬件。所以读写文件实质是请求操作系统打开一个文件描述符,通过操作系统接口读取数据。python内置了读写文件的函数

文件打开模式

打开模式执行操作
‘r’以只读方式打开文件(默认)
‘w’以写入的方式打开文件,会覆盖已存在的文件
‘x’如果文件已经存在,使用此模式打开将引发异常
‘a’以写入模式打开,如果文件存在,则在末尾追加写入
‘b’以二进制模式打开文件
‘t’以文本模式打开(默认)
‘+’可读写模式(可添加到其他模式中使用)
‘U’通用换行符支持
读文件

读文件用内置的open()函数,传入文件名和标示符

例如:

f=open('D:\\learnpython\\hello.py','r')

标示符标示读。接下来用read()就可以读取文件全部内容。python会把导读出来的内容读到内存,用str表示。

用close关闭文件,注意:文件使用完必须关闭文件。会占用系统资源

>>> f.read()
'def down(st,left):\n  if left-st==0:\n    return 1\n  elif left-st<0:\n    return 0\n  else:\n    left=left-st\n    return down(1,left)+down(2,left)+down(3,left)\ndef  '
>>> f.close()

使用try…finally来避免IOError

try:
    f=open('/path','r')
    print(f.read())
finally:
    if f:
        f.close()

还有一种比上面简单得多的方法,使用with语句,代码简介并且不用使用close方法

with open('/path/file','r') as f:
    print(f.read())

read(size)每次最多读取size个字节的内容

readline()每次读取一行的内容

readlines()读取所有内容,并按行返回list

file-like object 包括file,内存的字节流、网络流、自定义流等,他们都是有个read()方法的对象。

如果要读取二进制文件需要用‘rb’模式

读取非UFT-8编码的文件,需要向open()函数传入encoding参数

>>> f = open('/Users/michael/gbk.txt', 'r', encoding='gbk',errors='ignore')
>>> f.read()

open()函数还有一个errors参数 ,如果我们选择errors=‘ignore’。那么如果出现非法编码字符,会直接忽略。

写文件

还是用open函数,传入‘w’或者‘wb表示写文本文件或者写二进制文件

>>> f=open('test_file.py','w')
>>> f.write('hello')
5
>>> f.close()

我们不断使用write写入的内容先被存放在内存中,他会在空闲时间慢慢写入,只有使用了close()方法后内存中所有内容才会被写入磁盘中。所以一不要忘记close否则可能会导致内容部分丢失。

使用‘w’模式,新内容会覆盖原来的内容,如果需要追加内容可以使用‘a’模式写入

为了保证每次open后,我们都关,我们还是使用with语句

with open('D:\\learnpython\\test_file.py','w') as f:
    f.write('hello,world')

文件对象方法

文件对象方法执行操作
f.close()关闭文件
f.read([size=-1])从文件读取size个字符,当未给定size或给定负值的时候,读取剩余的所有字符,然后作为字符串返回
f.readline([size=-1])从文件中读取并返回一行(包括行结束符),如果有size有定义则返回size个字符
f.write(str)将字符串str写入文件
f.writelines(seq)向文件写入字符串序列seq,seq应该是一个返回字符串的可迭代对象
f.seek(offset, from)在文件中移动文件指针,从from(0代表文件起始位置,1代表当前位置,2代表文件末尾)偏移offset个字节
f.tell()返回当前在文件中的位置
f.truncate([size=file.tell()])截取文件到size个字节,默认是截取到文件指针当前位置
StringIO和BytesIO

OS模块:python内置的os模块可以直接调用操作系统提供的接口函数

StringIO:在内存中读写str

>>> from io import StringIO
>>> f=StringIO('hello!\nhi!\ngoodby')
>>> while True:
...     s=f.readline()
...     if s=='':
...         break
...     print(s.strip())
...
hello!
hi!
goodby

使用getvalue用于获取写入后的str

BytesIO:在内存中读写bytes。使用方法和StringIO类似

>>> f.write('中文'.encode('utf-8'))
6
>>> print(f.getvalue())
b'\xe4\xb8\xad\xe6\x96\x87'

OS模块

目录添加和删除

>>> os.path.join('/learnpython','test')   #表示完整路径,使用join可以处理不同操作系统分隔符的问题
'/learnpython\\test'
>>> os.mkdir('/learnpython/test')   #新建目录
>>> os.rmdir('/learnpython/test')    #删掉目录

路径合一是用os,path,join()函数,可以处理不同操作系统分隔符的问题

>>> os.path.split('/learnpython/hello.py') #用os.path.split()进行分割路径
('/learnpython', 'hello.py')
>>> os.path.splitext('/python/to/file.txt')  #`os.path.splitext()`可以直接让你得到文件扩展名
('/python/to/file', '.txt')

复制文件使用 shutil模块(可以看做随时os模块的补充)提供的copyfile()函数

过滤文件名的例子

>>> [x for x in os.listdir('.') if os.path.isfile(x) and os.path.splitext(x)[1]=='.dll']
['ApplePushDirect.dll', 'AppleVersions.dll', 'ASL.dll', 'AVFoundationCF.dll', 'CFNetwork.dll', 'CoreADI.dll', 'CoreAudioToolbox.dll', 'CoreFoundation.dll', 'CoreFP.dll', 'CoreGraphics.dll', 'CoreKE.dll', 'CoreLSKD.dll', 'CoreMedia.dll', 'CoreText.dll', 'CoreVideo.dll', 'Foundation.dll', 'gnsdk_dsp.dll', 'gnsdk_manager.dll', 'gnsdk_musicid.dll', 'gnsdk_submit.dll', 'icudt55.dll', 'iTunesAdmin.dll', 'JavaScriptCore.dll', 'libcache.dll', 'libdispatch.dll', 'libicuin.dll', 'libicuuc.dll', 'libtidy.dll', 'libxml2.dll', 'libxslt.dll', 'MediaAccessibility.dll', 'objc.dll', 'pthreadVC2.dll', 'QuartzCore.dll', 'SQLite3.dll', 'WebKit.dll', 'WTF.dll', 'zlib1.dll']
序列化

序列化:把变量从内存中变成科存储或传输的过程称之为序列化,pickling

反序列化:把变量内容从序列化的对象重新读入内存称为反序列化unpickling

python用pickle模块实现序列化

pickle.dumps()可以把任意对象序列化成一个bytes,然后把bytes写入文件。

也可以用pickle.dump()直接把对象序列化后写入一个file-like object

这样就可以把对象写入到磁盘了

之后我们通过pickle.load()的方法把file-like object 中直接反序列划出对象

pickle可能有不兼容的问题,所以只能用于保存不重要的数据。

JSON

json可以使我们在不同编程语言传递对象,json表示的对象就是标准的JavaScript语言的对象。

python同样提供了json模块,提供完善的python对象到json格式的转换

>>> import json
>>> d=dict(name='jack',age='20',score='100')
>>> json.dumps(d)
'{"name": "jack", "age": "20", "score": "100"}'

dumps()方法返回一个str,内容就是标准的JSON。类似的,dump()方法可以直接把JSON写入一个file-like Object

反序列化使用loads()把json字符串反序列化,使用load()从file-like object中读取字符串并反序列化

python的dict可以直接序列化为json的{}

补充:

dumps内有一个default可选项,它能够将任意一个对象序列化为一个json的对象,需要设定一个专门的转换函数然后传进去,这样类的实例会被转换函数转成dict,再顺利序列化为json

def student2dict(std):
    return {
        'name': std.name,
        'age': std.age,
        'score': std.score
    }
>>> print(json.dumps(s, default=student2dict))
{"age": 20, "name": "Bob", "score": 88}

当然还有一种通用方法将class的实例转为dict。

print(json.dumps(s, default=lambda obj: obj.__dict__))

每一个class的实例几乎都有一个__dict__的属性,他是一个dict,存储着实例的变量。

反序列化的时候,用loads()转换为dict对象。然后用object_hook函数负责把dict转为类的实例。

def dict2student(d):
    return Student(d['name'], d['age'], d['score'])
>>> json_str = '{"age": 20, "score": 88, "name": "Bob"}'
>>> print(json.loads(json_str, object_hook=dict2student))
<__main__.Student object at 0x10cd3c190>
总结:文件这一章新概念非常多,花了整整一天来学习该章内容。感觉还需要更多的练习来强化该章节的内容
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值