python初学之文件操作

 

本次博客将从以下四个方面介绍文件操作:

  • 1、文件操作介绍
  • 2、os模块详解
  • 3、json模块详解
  • 4、pickle模块详

01 文件操作介绍 

1.什么是文件?

  • 广义的“文件”指公文书信或指有关政策、理论等方面的文章。
  • 文件的范畴很广泛,电脑上运行的如杀毒、游戏等软件或程序都可以叫文件。
  • 日常中的数据存储在纸上, 而计算机的数据存储在硬盘上的。

文件对象的常用方法如下: 

seek(offset, from)有2个参数: offset:偏移量 from:方向
0: 表示文件开头 ;(常用)
1: 表示当前位置 ;
2: 表示文件末尾(常用)
1). 把位置设置为 : 从文件开头 , 偏移 5 个字节
2). 把位置设置为 : 文件最开始
3). 把位置设置为 : 文件最末尾

2.文件的作用

  • 电脑中的文件包括了文档、图片、视频、程序组件等,每个类型的文件都有不同的作用或功用,
  • 例如一个程序通常由主程序、动态库、配置文件等组成,这些也是文件,起到支持程序运行的作用。
  • 默认数据是加载到内存中,结果 也是保存到内存中, 程序执行结束,所有的数据释放。

3.文件的打开及相关操作

  • python,使用open函数,可以打开一个已经存在的文件,或者创建一个新文件。
  • 如果文件不存在那么创建,如果存在那么就先清空,然后写入数据
  • 比如:open(文件名,访问模式) e.g. f = open('test.txt', 'w')
1)open函数读取文件操作:(f = open('doc/hello.txt,mode=r'))
 
打开文件的模式:
 
要读取二进制文件,比如图片、视频等等,用 'rb', 'wb', 'ab' 等模式打开文件即可 .
 
 
# 打开文件,默认的打开模式是'r'
f = open('pi_digits.txt')
print(f.read())
 

结果:

注意:没有限定访问模式的时候, 默认访问模式为读‘r’模式,这种情况下是不能进行写‘w’模式的,如下:

# 打开文件,默认的打开模式是'r'
f = open('pi_digits.txt')
print(f.read())
# io.UnsupportedOperation: not writable
f.write('hello')

 可见写‘w’模式运行失败。

注意:但如果限定了文件的读取模式为读(mode=r)时,文件如果不存在,会直接报错; 就只能读已存在的文件,不能创建一个新文件了。 如下:

# mode=r, 文件doc/hello.txt不存在,直接报错,不能新建文件
f = open('doc/hello.txt,mode=r')
print(f.read())

#结果:
# FileNotFoundError: [Errno 2] No such file or directory: 'doc/hello.txt'

2)open函数多行读取文件:当文件比较大时, 使用readline方法读取.

from collections.abc import Iterable
#1)读取整个文件内容
f = open('pi_digits.txt', 'r')
print(f.read())
print('*'*50)

# 2)当文件比较大时, 使用readline方法读取.
f.seek(0, 0)                      # 将指针移动到文件最开始,读取第一行  
print(f.readline())
f.seek(5, 0)                    # 将指针移动到文件最开始, 然后指针向右移动5个字节。
print(f.readline())
print(f.readline())              #读取读取紧跟着的下一行
print('*'*50)

3)open函数逐行读取文件:当文件比较小时, 使用readlines方法读取

#1)读取整个文件
from collections.abc import Iterable
f = open('pi_digits.txt', 'r')
print(f.read())
print('*'*50)

#2) 当文件比较小时, 使用read、readlines方法读取.
f.seek(0, 0)                 #将指针移动到文件最开始,
print(f.readlines())

4)open函数以写的方式读取文件:(f = open('doc/hello.txt', mode='w'))

# mode=w, 1). 文件不存在,会自动创建文件; 2). 只能write   3). 自动清空文件内容
f = open('doc/hello.txt', mode='w')
f.write('hello world\n')
print("写入成功......")

 打开生成的文件hello.txt,会看到编辑的内容“hello world”

注意:当限定模式为写模式的时候(mode=write)的时候,是不能读取文件的,如:

# mode=w, 1). 文件不存在,会自动创建文件; 2). 只能write   3). 自动清空文件内容
f = open('doc/hello.txt', mode='w')
f.write('hello world\n')
print("写入成功......")
print("读取文件中...", f.read())      #添加读取行,结果会报错

发现此时读取文件失败了。

5)文件的附加(mode=a+)

  •  如果想要给文件 添加内容,而不是覆盖 原有的内容,可以附加模式打开文件,
  • 附加模式打开文件时,python不会在返回文件对象前清空文件,
  • 而我们写入到文件的内容 都将添加到文件末尾,
  • 如果指定 的文件不存在,python 会建一个空文件 
f = open('doc/world.txt', 'a+')
# 移动指针到文件最开始
f.seek(0, 0)
print(f.read())                          #可读
f.write('hello python\n')                 #可写(追加)

print(f.read())

 

注意图中打印了四个“hello python”的原因是我运行了三次程序导致的,一直运行会一直追加。

6)文件对象的属性:

f = open('doc/world.txt', 'a+')

print(f.closed)                       #文件未关闭,False
print(f.mode)
print(f.name)

f.close()                               #关闭文件
print("关闭文件后.....")                   #关闭后,Ture
print(f.closed)
print(f.mode)
print(f.name)

7)文件对象是可迭代对象

from collections.abc import Iterable
f = open('pi_digits.txt', 'r')

print(f.read())
print('*'*50)

# 名词: 可迭代对象: 可以通过for循环遍历的对象
print("文件对象时可迭代对象吗? ", isinstance(f, Iterable))
for index, line in enumerate(f):
    print("第%s行" %(index+1), line)

8)文件与文件之间的写入:

#需求: 将hello.txt文件后5行写入pi_digits.txt文件
f1 = open('hello.txt')
tail_five_line = f1.readlines()[-5:]
print(tail_five_line)
print(len(tail_five_line))
f2 = open('pi_digits.txt', 'a+')
f2.writelines(tail_five_line)
f = open('pi_digits.txt')

print(f.read())
print("write ok")

图中原因是我运行了四遍程序导致的。

9)文件的关闭

方法一 : 调用 close() 方法 关闭文件。
文件使用完毕后必须关闭,因为文件对象会占用操作系统的资源,并且操作系统同一时间能打开的文件数量也是有限的:如:
f = open('doc/world.txt',)
print(f.read())
print(f.closed)

f.close()                             #关闭文件
print("关闭文件后.....")
print(f.closed)

 
方法二 : Python 引入了 with 语句 来自动帮我们调用 close() 方法:
 
(1)with 语句工作原理
  • python中的with语句使用于对资源进行访问的场合,
  • 保证不管处理过程中是否发生错误或者异常都会自动执行规定的(“清理”)操作,释放被访问的资源
  • 比如有文件读写后自动 关闭、线程中锁的自动获取和释放等。
with open('hello.txt') as f:
    print('in with:', f.closed)     # False
    print(f.readlines()[-1])        #打印目标文件的倒数第一行内容
print('out with:', f.closed)        # True

10)项目案例:文件的备份Demo(os)

import os
src_filename = input("要拷贝的文件: ")
# 1). 判断文件是否存在
if os.path.exists(src_filename):
    dst_filename = input("目标文件: ")
    # 2). mode='r'打开文件读取文件内容
    # 注意: 要读取二进制文件,比如图片、视频等等,用'rb', 'wb', 'ab'等模式打开文件即可.
    src_f = open(src_filename, 'rb')
    content = src_f.read()

    # 3). mode='r'打开文件写入要拷贝的文件内容
    dst_f = open(dst_filename, 'wb')
    dst_f.write(content)

    # 4). 关闭文件对象
    src_f.close()
    dst_f.close()

    print('拷贝成功')
else:
    print("要拷贝的文件%s不存在" %(src_filename))

运行结果:

可见运行成功!

 

02 json模块详解

1.定义:

  • JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。它基于ECMAScript一个子集。
  • JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C、C++JavaJavaScriptPerlPython)
  • 这些特性使JSON成为理想的数据交换语言。易于人阅读和编写,同时也易于机器解析和 生成(一般用于提升网络传输速率)

2.python类型数据和JSON数据格式互相转换规则

1.注意:python中str类型到JSON中转为unicode类型,None转为null,dict对应object; pyhton中的集合不能转成json格式。

2.

3.序列化及反序列化常用参数

json.dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True,
allow_nan=True, cls=None, indent=None, separators=None,
encoding="utf-8", default=None, sort_keys=False, **kw)
 
ensure_ascii=False: 中文存储需要设定
indent=4: 增加缩进,增强可读性,但缩进空格会使数据变大
separators=(',',':'): 自定义分隔符 , 元素间分隔符为逗号, 字典 key value 值的分隔符为冒号
sort_keys=True: 字典排序
 

如:1.编码,存储json数据,(python转json),以字典为例:

import json
info = dict(user1='00000', user2='11111', 用户3='33333')

# 编码: 1)字典转成json数据格式
json_info = json.dumps(info)
print(info, json_info)
print(type(info), type(json_info))

# 编码: 2)字典转成json并存储未文件
json.dump(info, open('doc/info.json', 'w'), indent=4, ensure_ascii=False)
print("写入json文件成功")

可见转json并 文件存储成功,此时我们直接查看是不能识别所有的信息的。那么就需要对json文件 进行加载。

如:2.解码,加载json文件:(json转python):

import json
filename = 'doc/info.json'
# 3)解码: 将文件中的json数据转换成python对象进行处理
python_info = json.load(open(filename))
print(python_info)
print(python_info.get('用户3'))

4.自定义复杂数据类型编解码

例如我们碰到 集合对象 , datetime 对象,或者自定义的类对象等 json 默认不支持的数据类型时,我们就需要自定义编解码函数。
有两种方法来实现自定义编解码。
 
import datetime,json

def time2str(obj):
    #python to json
    if isinstance(obj,datetime.datetime):
        json_str = {"datetime":obj.strftime.datetime("%Y-%m-%d %X")}
    return json_str

def str2time(json_obj):
    #json to python
    if "datetime" in json_obj:
        date_str,time_str = json_obj["datetime"].spllit('')
        date = [int(x) for x in date_str.split('_')]
        time = [int(x) for x in time_str.split(':')]
        dt = datetime.datetime(date[0],date[0],date[1],date[2],time[0],time[1],time[2])
        return dt
    return json_obj

dt = datetime.datetime.now()
a = json.dumps(dt,default=time2str)
print(a)
print(json.loads(a,object_hook=str2time))


#{"datetime":2019-12-17 10:57:35"}
#2019-12-17 10:57:35

2)

from datetime import  datetime
from datetime import  date
import json


def time2str(dateObj):
    return  str(dateObj)

dt = datetime.now()
today = date.today()


# 自定义编码和解码
with open('doc/date.json', 'w') as f:
     # Object of type date is not JSON serializable
    json.dump(today, f, default=time2str)
    print('dump ok')

注意:json的缺点:不能存储集合类型,python特有的日期类型不能存储,自定义对象不能存储,因此引入了pickle模块。

03 pickle模块(仅支持python)

1.定义

  • python的pickle模块实现了python的所有数据序列和反序列化。与JSON不同的是pickle不是用于多种语言间的数据传输,
  • 仅作为python对象的持久化或者python程序间进行互相传输对象的方法,
  • 因此它支持了python所有的数据类型
  • cPickle是pickle模块的C语言编译版本相对速度更快。

2.json和pickle模块的区别

  1. JSON只能处理基本数据类型pickle能处理所有Python的数据类型。
  2. JSON用于各种语言之间的字符转换
  3. pickle用于Python程序对象的持久化或者Python程序间对象网络传输,
  4. 但不同版本的Python序列化可能还有差异

3.pickle数据的序列化

和json转换方式类似:python>>>>>>pickle-----(dump)

                                  pickle>>>>>>>python-----(load)

 

import pickle


# 1)编码
from datetime import date
today = date.today()
with open('date.pkl', 'wb') as f:
    pickle.dump(today, f)
    print('pickle dump ok')


# 2)解码: 反序列化
with open('date.pkl', 'rb') as f:
    today = pickle.load(f)
    print('pickle load ok')
    print(today)

5.小拓展(忽略注释行)


filename = 'doc/passwd.bak'
with open(filename) as f:
    for line in f:
        if not line.startswith('#'):
            print(line)
文件'doc/passwd.bak'的前10行,可见2,3,4行为注释行,运行结果我们看一下。

可见 被注释的2,3,4行被忽略了,直接跳过从第五行读取了。

 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值