史高治

新随笔 联系 管理
json:
 
json异于pickle,无乱码,各语言都支持,但Python各对象只直接接收int,str,(),[],{}。读入txt时只接受str,int变为str(int),()[]{}被json.dumps(*)换装为str后才行;反义词json.loads(json风格的str)返回()[]{}。
 
json虽是str类型,却有其独特风格,即引号只用双引号:因为有的编程语言如VBA并没用'而只用",故而通行各门语言的json也只用双引号。
 
import json
 
html1="{'a':1,'b':2,'中':3,'外':'国'}"
print(json.loads(html1))  #×
html2='{"a":1,"b":2,"中":3,"外":"国"}'
print(json.loads(html2))
******分割线******
import json
 
pythonType={'a':1,'b':2,'中':3,'外':'国'}
strStyle=str(pythonType)
print(type(strStyle),strStyle)  #无意义的单引号str:{'a': 1, 'b': 2, '中': 3, '外': '国'}
 
#中文不要转为u节码,各键值对换行显示,去除空格分隔符
jsonStyle=json.dumps(pythonType,ensure_ascii=False,indent='').replace(": ",":")
print(type(jsonStyle),jsonStyle)  #双引号str:{"a":1,"b":2,"中":3,"外":"国"}
 
with open('E:/temp.txt','a+',encoding='utf8') as f:  #写入或读取txt
    f.write(jsonStyle)  #非str类型如()[]{},转为json风格的str后才能写入txt;int则str(int)
    f.seek(0)   #.write(*)或.read()后,指针移到了文件尾,回到开头以正常使用该文件
    txt=f.read()
    print(type(txt),txt)
    pythonType=json.loads(txt)
    print(type(pythonType),pythonType)
**********************分割线**********************
key没套""的json字串:
 
import execjs
 
jsonStyle='{a:"111",b:22,c:3}'
pythonType=execjs.eval(jsonStyle)
**********************分割线**********************
让类对象貌似也能被json读入读出:
 
import json
 
class Student:
    def __init__(self,name,age,score):
        self.name=name
        self.age=age
        self.score=score
    def test(self):
        print(self.name,'good morning~')
 
s=Student('Bob',20,88)
# s.favorite='Python' #实例的私有属性可装入文件,但读回时无法和类挂钩,故不用
 
f=open('早上好.txt','r+')
json.dump(s.__dict__,f) #装入实例s的属性——1个字典到文件
# json.dump(s,f,default=lambda instance:instance.__dict__)    #改装实例s为json能接收的{}
f.seek(0)   #dump()和read()一样,用过之后指针都到了文末
w=json.load(f,object_hook=lambda d:Student(**d))    #文件内容做lambda的实参,返回新实例
f.close()
 
print(w.__dict__)
w.test()
****************************************分割线****************************************
csv:
 
Egのutf8编码的字串写入csv文件,并能用Excel正常打开:
 
import codecs,csv
with open('test.csv','ab') as f:
    f.write(codecs.BOM_UTF8)
with open('test.csv','a',encoding='utf8') as f:
    wr=csv.writer(f)
    wr.writerow(['影片名','评分','概况','年份','类别'])
**********************分割线**********************
Egの读取csv文件的俩常用库——csv和pandas:
 
import csv,pandas as pd,requests
from io import StringIO
 
df=csv.DictReader(open('E:/students.csv'))  #文件;若with … as f,则用f.readlines()
for row in df:  #row是collections.OrderedDict对象
    print(df.fieldnames,row['姓名'],row.keys(),row.values(),sep='\n')
    break
 
df=pd.read_csv('E:/students.csv',encoding='gbk')    #文件路径字串,无需open
for row in df.iterrows():   #row是元组:(序号,pandas.Series对象)
    print(row[1][0],row[1]['姓名'],row[1].index,row[1].values,sep='\n')
    break
 
url='http://pythonscraping.com/files/MontyPythonAlbums.csv'  #不下载直接读自网络
file=StringIO(requests.get(url).text)
df=csv.reader(file)
headers=next(df)
for row in df:
    print(row)
****************************************分割线****************************************
txt:

open打开文件的几种mode:
文件无则报错:r读,r+读后再f.seek(0)可覆盖写;
文件无则新建:a+末尾写并在f.seek(0)后可读,a末尾写;w清空写,w+清空写后再f.seek(0)可读。
 
a*或w*模式所新建的文本,纯英文编码会坚持utf8,写入有中文才能让指定的gbk生效。
 
相较直接open,变身为【with open(filepath) as f】的优点:with可自动open和close文件;而且把文件对象f当做迭代对象,将自动处理IO缓冲和内存管理,无需担心几个G的大文件的处理。
**********************分割线**********************
Egの各txt的编码不详,统一转换为gbk:
若特殊字符出没于ANSI而非utf8文件,则utf8和gbk都不能解码,只能抛弃这1行。
 
import pandas as pd,os
from tkinter.filedialog import askopenfilenames as ofn
from gevent import monkey;monkey.patch_all()
from gevent.pool import Pool
 
#法1のpandas读写一条龙:不过utf8和gbk都不能解码的那些行,只能换用法2弃之
def changeCoding1(coding,file):
    newfile=file[::-1].replace('.','.)wen(',1)[::-1]
    with open(file) as f:   #未.read()的open对象,可让pandas间接支持中文路径
        try:
            df=pd.read_table(f,skip_blank_lines=False,encoding='utf8')
        except:
            f.seek(0)    #pd.read_table(f),相当于f用指定或默认编码作.read()
            df=pd.read_table(f,skip_blank_lines=False,encoding='gbk')
    df.to_csv(newfile,index=False,encoding=coding)
 
#法2の边读边写:open1读为二进制+逗号语法+逐行解码并去干扰后给open2抄写
def changeCoding2(coding,file):
    newfile=file[::-1].replace('.','.)wen(',1)[::-1]
    with open(file,'rb') as r,open(newfile,'w',encoding=coding) as w:
        for index,line in enumerate(r):  #各行及\n的list,用[i]则补全.readlines()
            try:w.write(line.decode('utf8').rstrip()+'\n')  #*b模式打开,行尾会多个\r\r
            except:
                try:w.write(line.decode('gbk').rstrip()+'\n')
                except:print(f'{file}的第{index+1}行解码失败')
 
def main(func):
    coding='gbk'
    files=ofn(initialdir=os.path.dirname(__file__),title='请选择要转换编码的各文本')
    p=Pool(size=4)
    [p.spawn(func,coding,file) for file in files]
    p.join()
 
if __name__ == '__main__':
    main(changeCoding2)
**********************分割线**********************
Egの遍历目录下的文本或excel,把证件的8位生日、手机的4位城市,都改为*:
 
import os,re,pandas as pd
 
def handleText(file):
    try:
        f=open(file,'r+')
        text=f.read()
    except:
        f=open(file,'r+',encoding='utf8')
        text=f.read()
    text=re.sub('(\d{6})\d{8}',r'\1'+'*'*8,text)
    text=re.sub('(\d{3})\d{4}',r'\1'+'*'*4,text)
    f.seek(0)
    f.write(text)
    f.close()
 
def handleExcel(file):
    df=pd.read_excel(open(file,'rb'),skip_blank_lines=False)
    df.replace('(\d{6})\d{8}',r'\1'+'*'*8,inplace=True,regex=True)
    df.replace('(\d{3})\d{4}',r'\1'+'*'*4,regex=True).to_excel(file,index=False)
 
def main(folderPath):
    allfiles=[]
    for folder,useless,files in os.walk(folderPath):
        allfiles.extend([os.path.join(folder,file) for file in files])
    for file in allfiles:
        suffix=os.path.splitext(file)[-1][1:]
        if suffix in ['txt','csv','py','md']:
            handleText(file)
        elif suffix in ['xls','xlsx']:
            handleExcel(file)
 
if __name__ == '__main__':
    folderPath='D:\待遍历文件夹'
    main(folderPath)
****************************************分割线****************************************
xlsx:
 
Egの新建及打开xlsx文件:
 
from openpyxl import Workbook   #新建工作簿
wb = Workbook()
ws = wb.active
ws.title='豆'
ws.append(['书名', '评分', '作者', '网址'])
ws.append(['龙符', '9.9', '梦入神机', 'http://book.zongheng.com/book/523438.html'])
wb.save('E:\豆瓣.xlsx')
 
from openpyxl import load_workbook  #打开已存在的工作簿
from openpyxl.styles import Font
wb=load_workbook('E:\豆瓣.xlsx')
ws=wb.worksheets[0]  #获取第1张表;②通过表名获取:wb['豆']
print(ws.max_row)
ws['A1'].font=Font(name='微软雅黑', size=12)    #ws['A1'].number_format='@' 
wb.save('E:\豆瓣.xlsx')
posted on 2017-10-19 17:39  史高治  阅读(325)  评论(0编辑  收藏  举报