python文件读写

文件读写

Python内置了文件读写的函数,用法和c语言是兼容的
工作原理:从做系统不允许在磁盘上直接读写文件,多以读写就是请求os打开一个文件对象【被称为文件的描述符】,然后,通过os提供的接口从这个文件对象中读取数据【读文件】,或者将数据写入到文件中【写文件】

1、常用文件读写

1.1、读文件

步骤:
 a、打开文件:open()
 b、读取内容:read()
 c、关闭文件:close()

import os
import pprint
"""
读文件:从磁盘到内存
写文件:从内存到磁盘

IO:Input/Output

IoError:当文件读取完毕,还继续读取
"""

# 一、打开文件
"""
open(path,flag,encoding,errors)
    path:需要打开的文件的路径,绝对路径、相对路径都可以,一般r“path”
    flag:以文件的方式:
        r:以只读的方式打开文件,文件描述符出现在文件的开头
        rb:以二进制的方式打开一个文件用于只读,文件描述符出现在文件的开头
        r+:打开一个文件用于读写,文件描述符出现在文件的开头
    encoding:编码格式,常用utf-8和gbk
    errors:惊醒读取文件的时候的无措处理,一般用异常,可忽略
"""
path = r"C:\Users\weichen\Desktop\shopping2\shopping_car\致橡树.txt"
# 以只读的方式打开
# f是一个变量,指向一个被打开的文件,被称为文件对象
f = open(path, "r", encoding="gbk")

"""
注意:
    1、如果flag采用的是rb,encoding则必须省略,否则报错
    2、如果flag采用的是r,如果文件格式是gbk,则可以省略encoding="gbk",
        如果文件格式是utf-8,则不能省略encoding = "utf-8"
"""

# 二、读取文件内容
# 1、read
# 1.1 默认读取文件中的所有内容
# 使用场景:读取内容较少的文件
# str1 = f.read()
# print(str1)

# 1.2一次读取指定字节的内容
# 使用场景:结合循环,读取内容较多的文件
# str1 = f.read(3)

#采用read(num)方式读取文件的全部内容,借助于循环
#在读取数据量大的文件时,一次读取的大小一般为1024
# size = os.path.getsize(r"C:\Users\weichen\Desktop\shopping2\shopping_car\致橡树.txt")
# print(size)
# num = 816
#
# while size>0:
#     str1 = f.read(num)
#     print(str1)
#
#     size -= num

# 2、readline
# 2.1一次读取一行内容
# str2 = f.readline()
# print(str2)

# 借助于循环读取全部的内容,入伏哦返回值为假,则表示没有内容可读

# result = f.readline()
#
# while result:
#     print(result)
#     result = f.readline()

# 2.2 readline(num),类似read(num),但是一般不这么用,使用目的是为了读取一行内容


# 2.3 readlines,按照行进读取,结果为一个列表,其中会显示换行符和空格
str3 = f.readlines()
# print(str3)
pprint.pprint(str3)

# 三、关闭文件
# 注意:关闭的文件的目的有时候为了系统资源的浪费
f.close()

1.2写文件

步骤:
a.打开文件:open()
b写入内容:write()
flush
c.关闭文件:close()

# 写文件
# 一、打开文件
"""
open(path,flag,encoding,errors)
    flag:文件的打开方式
        w:一写入的方式打开一个文件,文件描述符存在文件的开头
        wb:以二进制的方式打开一个文件的写入,文件描述符存在文件的开头
        w+: 打开一个文件用于读写,文件描述符出现在文件的开头
        a:append,在源文件内容的后面追加内容
"""
f = open(r"file1.txt","w",encoding="utf-8")

# 二、写入内容
f.write("你好hello1234")

# 一般写入内容后刷新,加快写入速度
f.flush()
# 三、关闭文件
f.close()

"""
总结:
    1、不管是读取文件还是写入文件,都需要打开文件,打开的方式取决于需要进行的操作
    2、如果时读取文件,则文件必须存在,二如果时写入文件,则文件可以不存在,在写入的过程会自动创建
    3、在写入文件的过程中,如果采用的时w,则覆盖,a,追加
    4、在进行文件读写的时候,一定要注意使用的编码格式和文件本身的编码格式需要保持一致,否则乱码
"""
with语句
# 文件读写的简写形式
# with.....as...
"""
通过with...as...,简化文件读写过程中的异常
优点:当文件读写完毕之后,可以自动关闭文件,不需要手动关闭

"""

# 读文件
# f知识一个变量,只是只想打开的文件对象
with open("致橡树.txt","r", encoding="gbk") as f:
    print(f.read())

# 写文件
with open("file1.txt","w",encoding="gbk") as f:
    f.write("浪里个浪")
    f.flush()
    
# 注意:一旦代码执行with...as..代码块,则文件会自动关闭,但是,对于变量不会引入新的作用域

2、csv文件的读写

读取文件

# 读取csv文件
import csv

def readcsv1(path):
    # 1.打开文件
    csvfile = open(path,"r")
    # 2.读取文件内容
    # 区别于普通文件,但会一个迭代对象,如果要获取具体内容,则可以遍历该可迭代对象
    result = csv.reader(csvfile)
    print(result)

    for content in result:
        # 可迭代对象当中的元素为列表
        print(content)
        
    # 关闭文件
    csvfile.close()


if __name__ == "__main__":
    readcsv1(r"csv1.csv")

# 二、# 读取csv文件
import csv

def readcsv1(path):
   with open(path,"r") as f1:
       result = csv.reader(f1)
       for content in result:
           print(content)


if __name__ == "__main__":
    readcsv1(r"csv1.csv")

写入文件

# 写入csv文件
import  csv

# 注意,向csv文件中写入任意的可迭代对象

def writecsv1(path):
    # 打开文件
    csvfile = open(path,"w")

    # 写入
    # 获取写入对象
    result = csv.writer(csvfile)
    # 写入
    # 列表
    # 字符串: 打碎重写
    # 字典:只写key

    result.writerow(["aaa", 'bbb', 'dd', 'cc'])
    
    # 关闭文件
    csvfile.close()

if __name__ == "__main__":
    writecsv1("csv2.csv")

3、编码和解码

乱码:utf-8存储中文 3个字节,gbk存储中文占用2个字节
注意:编解码格式要保持一致,如果不一致,修改文件本身的编码格式

path = r"text03.txt"

#1.编码
with open(path,"wb") as f1:
    str1 = "今天是个好日子today is a good day"
    f1.write(str1.encode("utf-8"))
#
# with open(path,"w",encoding="utf-8") as f1:
#     str1 = "今天是个好日子today is a good day"
#     f1.write(str1)


#2.解码
# with open(path, "rb") as f1:
#     data = f1.read().decode("utf-8")
#     print(data)

with open(path, "r", encoding="utf-8") as f1:
    data = f1.read()
    print(data)

pickle模块

在python中,如果要实现序列化和反序列化,可以使用pickle和json
【面试题:简述什么时序列化和反序列化】
序列化:将对象持久化到磁盘上,【写:weite】,英文表示为picking,serialiation
反序列化:将磁盘上的对象读取出来【读:read】,英文表示:unpicking

import  pickle

"""
pickle提供了简单的持久化功能,可以将对象以文本的形式存储到磁盘上
pickle只能在Python中使用,
Python中所有的数据类型【list,tuple,dict,set,str,对象】都可以通过pickle模块持久化到磁盘上

注意:通过pickle序列化之后的数据,人一般无法识别,只能计算机识别【区别于乱码】
"""

class Person(object):
    def __init__(self,name,age):
        self.name = name
        self.age = age

    def show(self):
        print("姓名:%s,年龄:%s" % (self.name,self.age))

p = Person("zhangsan",10)

#1.以普通文件的方式操作对象
#缺点:write只能写入字符串
#f = open(r"file1.txt","w",encoding="utf8")
#f.write(p)#TypeError: write() argument must be str, not Person
#f.close()

#2.思考问题:如果向文件中写入一个对象,该如何做?---》pickle模块

#2.1序列化【写】
"""
pickle.dump(obj,file)
    obj:将要写入文件的对象
    file:obj将要写入的文件对象,注意:file必须以二进制的方式打开,为wb
"""
#a。打开文件
f1 = open(r"obj.txt","wb")

#b.写入对象
pickle.dump(p,f1)

#c.关闭文件
f1.close()


#2.反序列化【读】
"""
pickle.load(file)
    file:将要读取的文件对象,注意:file必须以二进制的方式打开,为rb
"""
#a.打开文件
f2 = open(r"obj.txt","rb")

#b。读取对象
result = pickle.load(f2)
print(result)
result.show()

#c.关闭文件
f2.close()

"""
w,w+,wb都会覆盖源文件中的内容,
r,r+,rb都必须保证源文件存在
w,w+,wb,a如果文件不存在,会自动创建
"""

json模块

思考问题:将文本或者二进制数保存到文件中,使用write操作,如果将一个列表或者字典直接保存到文件中该如何实现?------》使用json格式保存数据

JSON:JavaScript Object Notation,本来是JavaScript语句中船舰对象的一种字面量方式,被广泛应用于跨平台的语言的数据交换【因为JSon时纯文本,任何系统任何编程语言都可以处理纯文本】

使用场景:在两种不同的编程语言之间传递对象,将数据序列化为josn,json表示出来就是一个字符串,可以被所有的语言读取,也可以存储到磁盘或者网络传输

在web开发中,不仅使用json,还使用xml,但是使用json较多,json更快,而且可以直接在web中读取

Python中的数据类型和json的数据类型的区别:
json    Python
object    dict
array    list
string    str
number   int/folat
true/false  True/False
null     None

注意:json和pick将数据序列化之后的区别

import  pickle
dict2 = dict(name="jack",age=10,score=100)
with open(r"pickle1.txt","wb") as f2:
    pickle.dump(dict2,f2)
import  json

#一、基本用法
#1.写【序列化】
"""
dump():将Python对象按照json格式序列化到文件中
dumps():将Python对象处理成json格式的字符串
"""
#1.1
dict1 = dict(name="jack",age=10,score=100)
print(dict1)
r1 = json.dumps(dict1)
print(r1)
print(type(r1))

#1.2
dict2 = dict(name="jack",age=10,score=100)
with open(r"data1.json","w",encoding="utf8") as f2:
    json.dump(dict2,f2)

#2.读【反序列化】
"""
load():将文件中的json数据反序列化为对象
loads():将字符串的内容反序列化为Python对象
"""
#2.1
str1 = '{"name": "jack", "age": 10, "score": 100}'
r1 = json.loads(str1)
print(r1)
print(type(r1))

#2.2
with open(r"data1.json","r",encoding="utf8") as f2:
    r2 = json.load(f2)
    print(r2)
    print(type(r2))


#练习:
#序列化
def jsonwrite(dict1):
    with open(r"data2.json","w",encoding="utf8") as f1:
        json.dump(dict1,f1)

    print("数据保存成功!")

#反序列化
def jsonread():
    with open(r"data2.json","r",encoding="utf8") as f2:
        result = json.load(f2)
        print(result)

if __name__ == "__main__":
    mydict = {
        "name":"狗蛋儿",
        "age":18,
        "qq":1736363,
        "friends":['王大锤',"马化腾"],
        "cars":[
            {"brand":"polo","price":100000},
            {"brand":"五菱宏光","price":50000},
            {"brand":"qq","price":20000}
        ]
    }
    jsonwrite(mydict)

    jsonread()

StringIO和BytesIO

数据的读写不一定只能在文件中操作,也可以在内存中操作,StringIO在内存中读写字符串,BytesIO在内存中读写字节,字节数据其实就是二进制数据

注意:StringIO和BytesIO是系统的类

from  io import  StringIO,BytesIO

#一、StringIO
#1.写入
#创建对象
si = StringIO()
#写入
#注意:将数据写入到了内存中
si.write("hello")
si.write("Python")
si.write("2141412")

#获取写入到内存中的数据
r1 = si.getvalue()
print(r1)

#2.读取
si2 = StringIO("hello\nPython\n2141412")
#全部读取
# r2 = si2.read()
# print(r2)
#按行读取
# r2 = si2.readline()
# print(r2)

while True:
    r2 = si2.readline()
    if r2 == "":
        break

    print(r2)

#二、BytesIO
#1.写入
bi = BytesIO()
#编码
# bi.write("中文fahjghahg".encode("utf-8"))
bi.write(bytes("中文fahjghahg",encoding="utf-8"))
print(bi.getvalue())

#2.读取
bi2 = BytesIO(b'\xe4\xb8\xad\xe6\x96\x87fahjghahg')
r2 = bi2.read()
print(r2)
#解码
#print(r2.decode("utf-8"))
print(str(r2,encoding="utf-8"))

collections

1.namedtuple

#1.namedtuple
from  collections import  namedtuple
"""
tuple是一个有序的集合
其中允许存储重复元素,但是,一旦被定义之后,将不可改变
"""

#需求:使用元组表示一个二维坐标
#方式一
tuple1 = (2,4)
#方式二
class Point(object):
    def __init__(self,x,y):
        self.x = x
        self.y = y
print(Point)
p = Point(2,4)
print(p.x,p.y)
p.x = 10
p.y = 20
print(p.x,p.y)

print("*" *20)

#方式三
#第一步:导入模块
#第二步:调用函数,定义了类
#namedtuple("名称",[属性])
Point = namedtuple("Point",["x","y"])
print(Point)
p = Point(2,4)
#第三步:访问属性
print(p.x,p.y)
# p.x = 10
# p.y = 20
# print(p.x,p.y)

"""
namedtuple是一个函数,它用来创建一个自定义的tuple对象
并且规定了tuple元素的个数,并可以用属性而不是索引访问元组中的元素

好处:可以很方便的定义一种新的数据类型,它具备元组的不可变性,又可以通过引用访问属性
"""

print(isinstance(p,Point))
print(isinstance(p,tuple))


Circle = namedtuple("Circle",['x','y','r'])

2.deque

from collections import  deque


"""
使用list存储数据,按照索引访问元素速度较快,但是,插入和删除的速度较慢,因为list是线性存储

deque是为了实现高效的插入和删除操作的双向列表

添加元素
    append:在末尾追加/appendleft:在头部添加
删除元素
    pop:删除末尾元素/popleft:删除头部元素
"""

queue = deque([2,3,4])
print(queue)

#添加
queue.append(5)
print(queue)
queue.appendleft(6)
print(queue)

#删除
queue.pop()
print(queue)
queue.popleft()
print(queue)

3.defaultdict

from  collections import  defaultdict

"""
普通的dict,如果访问了一个不存在的key,则会报出异常KeyError
"""
dict1 = {"a":1,"b":2}
v1 = dict1["a"]
print(v1)
# v2 = dict1["c"]
# print(v2)   #KeyError: 'c'

print(dict1)

#问题:如果key存在,则获取对应的value,但是如果key不存在,返回一个默认值,需要使用defaultdict

#defaultdict(有返回值的函数[,字典])
d = defaultdict(lambda : "aaaa")
print(d)
print(type(d))

#注意:和普通的dict相同,如果key不存在,dict[key] = value则表示将键值对添加到字典中
d["key1"] = 34
print(d)

#如果访问的key不存在,则默认获取的是函数的返回值
print(d["key2"])

4.OrderDict

from collections import  OrderedDict


"""
字典:key是无序的
"""

#字典的写法

#1.无序字典
dict1 = {"a":1}
print(dict1)
dict2 = dict(x=1,y=3)
print(dict2)
dict3 = dict([("a",1),("b",2),("c",3)])
print(dict3)

#2.有序字典
dict4 = OrderedDict([("a",1),("b",2),("c",3)])
print(dict4)


#练习:
od = OrderedDict()
od["2"] = 20
od["1"] = 10

print(list(od.keys()))

5.Couter

from  collections import  Counter

#需求:统计一个单词中每个字符出现的次数
data = input("请输入文本:")

#方式一
dict1 = {}

for ch in data:
    if ch not in dict1:
        dict1[ch] = 1
    else:
        dict1[ch] += 1
print(dict1)

#方式二
#Counter是Collections中提供的一个计数器
c = Counter()
for ch in data:
    c[ch] += 1
print(c)

print(type(c))
print(isinstance(c,Counter))
print(isinstance(c,dict))

#Counter实际上是dict的一个子类,专门用来统计可迭代对象个数
c = Counter()
for num in [2,3,43,43,3,3,3,3,22,100]:
    c[num] += 1
print(c)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值