Python-Visualization-Process the Json file

本文最后更新于:8 个月前

Python 编写工程项目时,对每份代码,编写流程基本都是 \[ \Large \textcolor{black}{调库}\normalsize \Longrightarrow \Large \textcolor{black}{全局变量}\normalsize \Longrightarrow \Large \textcolor{black}{装饰器}\normalsize \Longrightarrow \Large \textcolor{black}{子函数}\normalsize \Longrightarrow \Large \textcolor{black}{主函数}\normalsize \] 只要两者之间具有一定独立性,最好空开两行方便 \(\mbox{Debug}\) 。(这个真的是教训啊!!一定要全局,编写过程中使用复用性更高的代码,如使用 \(\mbox{len()}\) 获取迭代次数,避免数据换了后手动调浪费时间)

装饰器的使用

装饰器是为了在输出结果时告知当前运行函数名称,运行时间,方便快速定位 \(\mbox{Bug}\) 位置,一个经典装饰器的代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
import functools
def metric(fn):
@functools.wraps(fn)
def wrapper(*args, **kw):
print('start executing %s' % (fn.__name__))
start_time = time.time()
result = fn(*args, **kw)
end_time = time.time()
t = 1000 * (end_time - start_time)
print('%s executed in %s ms' % (fn.__name__, t))
return result
return wrapper

该装饰器告知开始运行函数、结束运行函数以及运行时间,在每次 def 'name_of_fuction' 前一行加入 @metric 便可以实现装饰器功能

获取目录下所有文件

由于本次工作数据量庞大(成千上万个文件),从本地特定目录下读取该目录的所有文件,使用 \(os\) 库中的 \(listdir\) 函数获取目录下的文件名与目录拼接在一起,代码如下:

1
2
3
4
5
6
7
import os
def get_list(target):
dirs = os.listdir(target) //获取目录下的文件名称并存为列表
file_list = [] //初始化空列表
for file in dirs: //遍历列表中的每一个文件名称
file_list.append(f"{target}/{file}") //加到原来文件目录后面
return file_list //得到一个具有该目录下所有文件位置的列表

异常处理

使用 \(\mbox{try}\)\(\mbox{except}\) 语法,前者后面语句出现错误则跳至 \(\mbox{except}\) 处,最好联合输出报错信息 \(\mbox{e}\) 以及错误所在文件搭配:

1
2
3
except Exception as e:
print(e)
//print(file)

在处理文件时容易发现“前端”的规范化有问题,此时 \(\mbox{try-except}\) 的作用体现得更加显著,多次套用异常处理语句即可

计数器功能

导入计数器所在库 from collections import Counter,单个计数器本质上就是单个字典,使用 类名 = Counter() 初始化,之后遇到什么就以字典的形式进行计数(Counter() 内部自动实现了遇到新 key 值计数为 \(1\) ,遇到旧 key 值计数器加 \(1\) ),由于存在多个、相互独立的列表,在实际运用中使用列表保存多个字典:

1
2
3
4
5
6
7
8
9
10
11
listDics = []
for i in range(0,len(dirLanguage)): //从 xlsx 中读取的二维列表(第几列第几个词)
tempDict = Counter() //代表具有计数器功能的空字典
listDics.append(tempDict) //形成字典列表
for file in tqdm(file_list): //遍历并打开所有文件
with open(file,"r",encoding = "utf-8",errors = "ignore") as f:
getTitle = json.load(f)["title"] //使用 json.load(f) 载入文件
for i in range(0,len(dirLanguage)): //对二维列表的每一列
for word in dirLanguage[i]: //对应计数每一列
listDict[i][word] += 1 //使用字典的方式计数

\(\mbox{json}\) 文件收放自如

从上个实例代码中可以看到,使用 json.load(f) 即可以实现读取对应 \(\mbox{json}\) 文件的内容,即为 \(\mbox{json}\) 文件的读取

与之相对的为 \(\mbox{json}\) 文件的写入,使用 json.dump(写入名称,打开的文件(如f),ensure_ascii = False, indent = 2),注意打开文件时类型为 \(\mbox{w\small+}\) ,为覆盖类型,例如

1
2
with open("./result.json","w+",encoding = "utf-8",errors = "ignore") as f:
json.dump(title_content,f,ensure_ascii = False, indent = 2)

可视化工作中的可视化( \(\mbox{tqdm}\)

导入进度条库 from tqdm import tqdm (in Arabic means progress, also in Spanish te quiero demasiado means I love you so much. ),在迭代器处加入 \(\mbox{tqdm}\) 就可以清晰地看到迭代所处位置,再也不用一直盯着闪烁的光标无脑等待了~~

1
for file in tqdm(file_list):

\(\mbox{Python}\) 交互式系统中可以达到这样效果,输入时保证可以需要输入就不会自动运行:

在大字符串中查找小字符串出现次数

使用字符串变量内置函数 \(str.\mbox{count}\),直接返回次数。造轮子的事情尽量少做:

1
str.count(find_str)

调试(工程能力的体现)

在编写代码中,尽管“前端”有可能背锅,但大部分的错误还是因为自己总像个小孩子一样“犯傻”,不过 \(\mbox{Python}\) 毕竟还是“大人”使用的工具,要学会定位 \(\mbox{Bug}\) 的能力:

1
from IPython import embed

\(\mbox{embed}\) 函数有点像 \(\mathbf{C}\large艹\) 中的断点调试,但是更好的一点是,在出现错误的地方打上 \(\mbox{embed}\) 后程序会在指定的地方停止,同时保留了当前所有的存储变量,向外提供执行任意输入代码的接口,在 \(\mbox{embed}\) 之后,\(\mbox{print}\) 出当前的存储变量,或者手动输入(也可以多行复制)运行接下来的代码快速找到相应问题。虽然最后来说很多问题都比较弱智,但是就是这些弱智问题的 \(\mbox{Debug}\) 很大程度影响了代码编写、维护以及(满足甲方需求)成功运行的总开发时长。


Python-Visualization-Process the Json file
https://lr-tsinghua11.github.io/2022/03/03/%E7%BC%96%E7%A8%8B/python%20%E5%8F%AF%E8%A7%86%E5%8C%96%E6%B5%81%E7%A8%8B/
作者
Learning_rate
发布于
2022年3月3日
许可协议