@Cleland
2019-09-26T01:18:23.000000Z
字数 7162
阅读 1191
你好,我是悦创。
有时我们存储得到的数据,并不需要使用数据库存储。仅仅就需要存储成哪些常用的文本格式,供给其他人使用。
本文的主要内容:
| 序号 | 知识点 |
|---|---|
| 1 | Python 操作文本 |
| 2 | Python 操作二进制流 |
| 3 | Python 操作 JSON(restful 风格) |
| 4 | Python 操作 Excel |
| 5 | Python 操作 World |
日常操作文件,许多时候并不是操作有难题,而是路径问题。
Python 标准库-OS:https://docs.python.org/3/library/os.html
import osfile = 'D:\\Python_project'# 判断文件夹是否存在if not os.path.exists(file):# 不存在则创建os.mkdir(file)import os# 获取当前目录file_name = os.getcwd()txt = 'python.txt'with open(os.path.join(file_name, txt), 'w') as f:f.write('Hello world!')
我写了一个创建文件夹的插件:(切记,不要重复造轮子)
你可以自行调用。
# -*- coding: utf-8 -*-# @Author :AI悦创# @DateTime :2019/9/16 16:08# @FileName :run_file.PY# @Function :功能# Development_tool :PyCharmimport osimport uuiddef mkdir_file(path):path = path + r'\baidu_img'print(path)# 去除首位空格path = path.strip()# 去除尾部 \ 符号path = path.rstrip("\\")# 判断路径是否存在# 存在 True# 不存在 FalseisExists = os.path.exists(path)# 判断结果if not isExists:# 如果不存在则创建目录# 创建目录操作函数# os.makedirs(path)os.mkdir('baidu_img')os.mkdir(r'baidu_img\{}'.format(uuid.uuid4()))# print(path + ' 创建成功')return Trueelse:# 如果目录存在则不创建,并提示目录已存在os.mkdir(r'baidu_img\{}'.format(uuid.uuid4()))return Trueif __name__ == '__main__':# 定义要创建的目录mkpath = os.path.dirname(__file__) #获取当前文件夹的绝对路径print(mkpath)# 调用函数mkdir_file(mkpath)
当然还有个轻便版本:
def mk_dir():"""用于创建放置图片的文件夹:return: 文件夹名称"""folder_name = input('请输入图片要存放的文件夹名称:>>> ')try:os.mkdir(r'{}'.format(folder_name))except FileExistsError:passreturn folder_name
有时候,我们不想浪费时间给文件起名字,那我们有什么可以简化我们取名字的流程呢?
有时你会这么起名:
index = 0for i in range(10):file_name = f'{i}.txt'print(file_name)index += 1# 输出0.txt1.txt2.txt3.txt4.txt5.txt6.txt7.txt8.txt9.txt[Finished in 0.2s]
还有一个更加 python 的方法 enumerate()
for index, i in enumerate(range(10)):file_name = f'{index}.txt, text:{i}'print(file_name)# 输出0.txt, text:01.txt, text:12.txt, text:23.txt, text:34.txt, text:45.txt, text:56.txt, text:67.txt, text:78.txt, text:89.txt, text:9[Finished in 0.1s]
剩下的就剩一个第三方库:UUID
import uuidfor i in range(10):file_name = '{uu}.txt, text:{i}'.format(uu=uuid.uuid4, i = i)print(file_name)# 输出<function uuid4 at 0x0000018B31031AF8>.txt, text:0<function uuid4 at 0x0000018B31031AF8>.txt, text:1<function uuid4 at 0x0000018B31031AF8>.txt, text:2<function uuid4 at 0x0000018B31031AF8>.txt, text:3<function uuid4 at 0x0000018B31031AF8>.txt, text:4<function uuid4 at 0x0000018B31031AF8>.txt, text:5<function uuid4 at 0x0000018B31031AF8>.txt, text:6<function uuid4 at 0x0000018B31031AF8>.txt, text:7<function uuid4 at 0x0000018B31031AF8>.txt, text:8<function uuid4 at 0x0000018B31031AF8>.txt, text:9[Finished in 0.2s]
这一部分,我主要给你讲 uuid 库的使用
import uuidfrom uuid import UUID# 基于时间戳print(uuid.uuid1())# 基于名字的MD5散列print(uuid.uuid3(UUID(int=9), "lvv"))# 基于随机数print(uuid.uuid4())# 基于名字的SHA-1散列print(uuid.uuid5(UUID(int=9), "lvv"))
Ps:当需要大批量下载图片或者文档的时候可以使用 UUID
一下知识点以此代码作为示例,最后输出结果显示在第三列。
with open('test.txt', '模式', encoding='utf8') as f:res = f.readable()print(f'readable:>>>{res}')
| 关键词(模式) | 作用 | 输出结果 |
|---|---|---|
| r | 读取文件(只读模式) | True |
| w | 创建文件,会覆盖源文件 | False |
| (只写模式【不可读,不存在则创建,存在则删除文件中的内容】) | False | |
| a | 追加文件,不存在会创建......(没什么卵用) | False |
| 【不可读,不存在则创建,存在则只追加内容】 | ||
| b | 操作二进制流 | False |
| + | rw 的集合(表示可以同时学习某个文件) | |
| r+ | 可读写文件【可读、可写、可追加】 | True |
| w+ | 写读 | True |
| U | U表示在读取时,可以将\r \n \r\n自动转换成\n |
首先我们需要先了解一下,计算机中文件访问的基础知识。事实上,计算机内核(kernel)对文件的处理相对比较复杂,涉及到内核模式、虚拟文件系统、锁和指针等一系列概念,这些内容我不会深入讲解,我只说一些基础但足够使用的知识。
我们先要用open() 函数拿到文件的指针。其中,第一个参数指定文件位置(相对位置或者绝对位置);第二个参数,如果是 'r'表示读取,如果是'w' 则表示写入,当然也可以用 'rw' ,表示读写都要。a 则是一个不太常用(但也很有用)的参数,表示追加(append),这样打开的文件,如果需要写入,会从原始文件的最末尾开始写入。
这里我插一句,在实际的工作中,代码权限管理非常重要。如果你只需要读取文件,就不要请求写入权限。这样在某种程度上可以降低 bug 对整个系统带来的风险。
用 a+ 代替 w 当 for 循环不得不写在 write 函数之外时候适用
with open('test.txt', 'a+') as f:f.write('Python'.encode())
文件有开启,就有关闭。
你或许想用下面的方法来读取文件:
text = "Hello World!"f = open('text.txt', 'w')f.write(text)f.close()
我个人更喜欢第一种方法,更加的 Python 程序员,而且 with 方法,可以有效防止你文件操作后,忘记关闭。造成占用内存或者内存溢出。
接下来,我来给你详细的说一说:
with open('test.txt', 'wb') as f:text = f.read()f.write('Python'.encode())
上面的代码并不能正常运行,只是提供例子。以下示例是可以正常运行的:
with open('test.txt', 'wb') as f:f.write('Python'.encode())with open('test.txt', 'w', encoding='utf8') as f:f.write('Python')
运行程序之后会在当前文件夹下生成 test.txt 文件,那读取操作呢?
with open('test.txt', 'r', encoding='utf8') as f:res = f.read()print(res)# 输出Python
接下来,我来补充一些:
关于 with open 公众号往期文章中有哦!
在拿到指针后,我们可以通过 read() 函数,来读取文件的全部内容。代码 text = f.read() ,即表示把文件所有内容读取到内存中,并赋值给变量 text。
这么做自然也是有利有弊:
| readline() | 读取行 |
|---|---|
| readlines() | 读取所有行(得到的数据是给列表) |
| readable() | 判断能否读取 |
示例:
比如我们现在有以下的文本你内容
PythonAI悦创-创造不同公众号:AI悦创欢迎关注!
我们来实际读取一下:
with open('test.txt', 'r', encoding='utf8') as f:res1 = f.readline()res2 = f.readlines()print(f'readline:>>>{res1}')print(f'readlines:>>>{res2}')# 输出readline:>>>Pythonreadlines:>>>['AI悦创-创造不同\n', '公众号:AI悦创\n', '欢迎关注!']
import requests,uuiddef get_img(url, headers):img = requests.get(url, stream = True, headers = headers)img_name = '{}.jpg'.format(uuid.uuid4())with open(img_name, 'wb') as f:chunks = img.iter_content(chunk_size=128)# 单位是字节for chunk in chunks:f.write(chunk)headers = {'Referer': 'http://image.baidu.com/search/index?tn=baiduimage&ipn=r&ct=201326592&cl=2&lm=-1&st=-1&fr=&sf=1&fmq=1567133149621_R&pv=&ic=0&nc=1&z=0&hd=0&latest=0©right=0&se=1&showtab=0&fb=0&width=&height=&face=0&istype=2&ie=utf-8&sid=&word=%E5%A3%81%E7%BA%B8','User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36','X-Requested-With': 'XMLHttpRequest', }if __name__ == '__main__':url = 'https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=316485425,4089915232&fm=26&gp=0.jpg'get_img(url,headers)
小块读取:避免一次性占满内存,减轻 CPU 压力,在读取大文件时候很有优势。
如果你电脑内存大的话,可以忽略这个小块传输。
Json (JavaScript Object Notation) 是一种轻量级的数据交换格式。Json 采用完全独立于语言的文本格式,这些特性使 Json 成为理想的数据交换语言。易于人阅读和编写,同时也易于机器解析和生成。
data:{"people":[{"firstName":"Brett","lastName":"Mclaughlin","email":"aaa"},{"firstName":"Jason","lastName":"Hunter","email":"bbb"},{"firstName":"Elliotte","lastName":'Harold',"email":"ccc"}]}
比如,我要获取其中的 firstName:Jason,该如何获取呢?
data["people"][1]["firstName"]
Ps:Json 只能使用英文输入法下的“双引号”
# json.dumps() 与 json.dump()import jsondata = {"name":"AI悦创","shares":100,"price":542.23}# 操作一# 把字典转换成 jsonres = json.dumps(data)# json.dumps() 需要加 s 否则将写入成为文件(但也不是这么编写的,下面有示例)print(res)print(type(res))# 输出{"name": "AI\u60a6\u521b", "shares": 100, "price": 542.23}<class 'str'># 操作二with open('data.json', 'w') as f:json.dump(data, f)# 输出保存成 json 格式文件,自行运行尝试# json.loads() 与 json.load()import jsondata = '{"name":"AI月悦创","shares":100,"price":542.23}'# 操作一res = json.loads(data)print(res)print(type(res))# 输出{'name': 'AI月悦创', 'shares': 100, 'price': 542.23}<class 'dict'># 操作二# data.json 文件中的内容:# --------------------{"name": "AI\u60a6\u521b", "shares": 100, "price": 542.23, "Love": 1314}# -----------------------------------with open('data.json', 'r') as f:data = json.load(f)print(data)print(type(data))# 输出{'name': 'AI悦创', 'shares': 100, 'price': 542.23, 'Love': 1314}<class 'dict'>
Json 模块提供了简单的编码 Json 格式的方法,主要是 json.dumps() 和 json.loads()
接口很少
而 json.dump() 和 json.load() 适用于写入文件的时候。
fp:代表文件
| 函数 | 作用 |
|---|---|
| json.dump() | 写入到文件 |
| json.dumps() | 将 Python 对象编码成 JSON 字符串(写入到字符串) |
| json.load() | |
| json.loads() | 将已编码的 JSON 字符串解码为 Python 对象 |
| 识记 | 以 s 为结尾的都是以 Terminal (命令行)交互 |
dump的功能就是把Python对象encode为 json 对象,一个编码过程。注意json模块提供了json.dumps和json.dump方法,区别是dump直接到文件,而dumps到一个字符串,这里的s可以理解为string。
前面两个是 Python 转换到 json (dumps 与 dump)
后面两个是 Json 转换到 Python (loads 与 load)
此处输入代码