【03】Python 文件读写 JSON
1 打开文件
文件操作步骤:
1、打开文件获取文件的句柄,句柄就理解为这个文件
2、通过文件句柄操作文件
3、关闭文件。
1.1 打开方法
f = open('xxx.txt') #需f.close()关闭文件
f = open(r'E:\PycharmProjects\Python3_study\Day3\n文件读写',encoding='utf-8') #'r'可以防止字符串在使用的时候不被转义
with open(<filename>,<mode>) as f1,open(<filename>,<mode>) as f2: #文件使用结束后自动关闭文件
1.2 打开模式
- a+
1 f = open('test.txt','a+', encoding = 'utf-8') 2 f.seek(0) #指针在末尾,需要将其移至开头 3 print(f.read()) #读出所有内容
1 hello world 2 你好,世界
- w+
1 f = open('test.txt','w+', encoding = 'utf-8') 2 f.seek(0) 3 print(f.read()) #发现原来的内容已清空 4 f.write('这是新的') 5 f.seek(0) 6 print(f.read()) #可以读到刚刚写入的内容
1 这是新的
- r+
1 f = open('test.txt','r+', encoding = 'utf-8') 2 f.write('这是r+') #写入后指针跑到了新写入内容的末尾 3 f.seek(0) 4 print(f.read()) #从开头开始替换
1 这是r+rld 2 这是新的
2 文件读
2.1 读文件方法
- f.readline():读文件的一行,文件指针移动到下一行
- f.readlines():读从文件指针当前位置至末尾的所有行,文件指针移动到末尾。取文件里面所有内容,返回的是一个list,每一行的内容放到一个list
- f.read():读从文件指针当前位置至末尾的所有内容,文件指针移动到末尾。读取文件里面所有的内容,字符串
- for line in f: 直接循环文件对象,每次循环的line是文件的当前行内容,进入下一循环,则循环文件的下一行的内容
1 f = open('file.txt','r',encoding='utf-8') # 默认是当前路径 2 print('1=====',f.readline()) #读取文件一行的数据 3 print('2=====',f.readline()) #读取文件第二行的数据,即接下来一行 4 print('3=====',f.readlines()) #读取文件所有的数据,返回一个列表(从指针开始) 5 print('4=====',f.read()) # 获取文件里的所有内容(从指针开始)
2.2 日志分析
1 #写脚本每隔一分钟读日志文件,一分钟访问超200,禁止访问 2 3 #1读取文件内容,获取ip 4 #2把每个ip地址存起来 . 5 #3判断ip访问的次数是否超过200 6 #4加入黑名单 print 7 8 import time 9 10 point = 0#初始位置 11 12 while True: 13 14 f = open('access.log','r', encoding = 'utf-8') 15 IP = {} 16 17 f.seek(point) 18 19 for line in f: #一行一行读 20 str = line.split()[0] #split():通过指定分隔符对字符串进行切片,默认为所有的空字符,包括空格、换行(\n)、制表符(\t)等。 21 count = 0 22 if str in IP: 23 IP[str] += 1 24 else: 25 IP[str] = 1 26 27 point = f.tell() 28 29 f.close() 30 31 for k, v in IP.items(): 32 if v > 200: 33 print(k)
3 文件写
3.1 写文件方法
- f.writelines(listname):写一个list。类似于 for i in list: f.write(i)。所以,虽然writelines()可以写入string及list,但是字符串最好用write(),list最好用writelines()。自动循环,将list每一个元素追加写到文件中,如果想加换行符,可以将换行符放在list表里
- f.write(str):写一个字符串。不能自动循环,参数可自行加换行符,如 f.write('\n'+name)
- flush(): write后再调用flush,会将缓冲区里的内容立即写到磁盘上。写文件机制:cpu->内存->磁盘(为了提高效率,内存有缓冲区,当缓冲区满了,再将缓冲区的内容写到磁盘上)。
4 修改文件
4.1 方法一 不常用
1 # 文件修改的方法: 2 # 1、简单粗暴直接(适用于数据量少的情况) 3 # 1)读出来文件所有内容,保存为一个变量 4 # 2)对字符串变量进行处理 5 # 3)除旧存新 6 with open('a.data','a+',encoding='utf-8') as f: 7 f.seek(0) 8 data = f.read() #获取原来的内容 9 print('修改前:%s'%data) 10 new_data = data.replace('你','You') 11 print('修改后:%s'%new_data) #修改内容 12 f.seek(0) 13 f.truncate() # 清空文件内容,需要将文件指针移到头部再清空 14 f.write(new_data) #将修改后的内容存入文件 15 f.flush()
1 修改前:你好, 2 地球! 3 修改后:You好, 4 地球!
4.2 方法二 常用★
1 # 高效修改(一行一行修改) 2 # 1)循环取每一行,去除前面的空格 3 # 2)去除空行 4 # 3)你替换成you 5 # 4) 写到新文件里 6 # 5)把原来文件删除,把新文件的名字改成原文件的名字 7 import os 8 with open('a.data','r',encoding='utf-8') as f1, open('a2.data','w',encoding='utf-8') as f2: 9 for line in f1: # 1)循环取每一行,去除前面的空格 10 line = line.lstrip() # 1)去除前面的空格 11 if line: # 2)去除空行 12 print('修改前:%s'%line) 13 line = line.replace('You','你们') # 3)You替换成你们 14 print('修改后:%s'%line) 15 f2.write(line) # 4) 写到新文件里 16 os.remove('a.data'); # 5)把原来文件删除 17 os.rename('a2.data','a.data') # 5)把新文件的名字改成原文件的名字
1 修改前:You好, 2 3 修改后:你们好, 4 5 修改前:地球! 6 修改后:地球!
- os.remove('a.data'); #删除文件
- os.rename('a2.data','a.data') #修改文件名
5 JSON处理
5.1 json.load(file)
自动读取文件中的json,转换成字典
{ "xiaohei": "7891", "海龙": "111", "tanailing": "11111", "xiaojun": "123456" }
1 import json 2 f = open('stus.json',encoding='utf-8') 3 user_dic = json.load(f) 4 print(user_dic)
{'xiaohei': '7891', '海龙': '111', 'tanailing': '11111', 'xiaojun': '123456'}
5.2 json.dump(dic, file, indent=4, ensure_ascii=False)
把字典转成json串,并自动写入文件中。
dump参数是(字典,文件句柄,indent)。indent用于缩进美化json串的。
ensure_ascii=False用于写文件时有unicode时用,正常显示出中文来。
1 import json 2 stus = {'xiaojun':'123456','xiaohei':'7891','tanailing':'11111' 3 ,'海龙':'111'} 4 f = open('stus2.json','w',encoding='utf-8') 5 json.dump(stus,f,indent=4,ensure_ascii=False)
生成文件'stus2.json', 文件内容是由字典生成的json
5.3 json.loads(str)
把json串(字符串)转成字典。loads参数是字符串
1 import json 2 3 s=''' 4 { 5 "error_code": 0, 6 "stu_info": [ 7 { 8 "id": 309, 9 "name": "小白", 10 "sex": "男", 11 "age": 28, 12 "addr": "河南省济源市北海大道32号", 13 "grade": "天蝎座", 14 "phone": "18512572946", 15 "gold": 100 16 }, 17 { 18 "id": 310, 19 "name": "小白", 20 "sex": "男", 21 "age": 28, 22 "addr": "河南省济源市北海大道32号", 23 "grade": "天蝎座", 24 "phone": "18516572946", 25 "gold": 100 26 } 27 ] 28 } 29 ''' 30 31 res = json.loads(s) #json串(字符串),转成字典 32 print(res)
{'error_code': 0, 'stu_info': [{'id': 309, 'name': '小白', 'sex': '男', 'age': 28, 'addr': '河南省济源市北海大道32号', 'grade': '天蝎座', 'phone': '18512572946', 'gold': 100}, {'id': 310, 'name': '小白', 'sex': '男', 'age': 28, 'addr': '河南省济源市北海大道32号', 'grade': '天蝎座', 'phone': '18516572946', 'gold': 100}]}
5.4 json.dumps(dic,ensure_ascii=False)
把字典转成json串(字符串),loads参数是字典,需要手动write
1 import json 2 stus = {'xiaojun':'123456','xiaohei':'7891','tanailing':'11111','海龙':'111'} 3 res2 = json.dumps(stus,indent=8,ensure_ascii=False) 4 print(res2)
{ "xiaojun": "123456", "xiaohei": "7891", "tanailing": "11111", "海龙": "111" }
参数说明:
- 输出中文需要指定ensure_ascii=False,如果使用默认配置, 输出的会是‘ASCII字符
- indent参数根据数据格式缩进显示,读起来更加清晰 (数值代表缩进的位数)