Python实例(三)

如何设置文件的缓冲

文件内容写入到硬件设备时,使用系统调用,这类I/O操作的时间很长,另外对于磁盘这类块设备,读写不是一个字节一个字节完成的,而是按块,因此你写入一个字节和写入4096个字节(假设一个块为4096个字节)用时是相同的。为了提高效率,就要减少I/O操作的次数,例如文件通常使用缓冲区(凑够一个块的数据才进行系统调用)。

文件的i/o操作的缓冲行为分为:
全缓冲:同系统及磁盘块大小有关,n个字节后执行一次写入操作
行缓冲:遇到换行符执行一次写操作
无缓冲:立刻执行写操作

解决方案:
全缓冲:open函数的buffering设置为大于1的整数n,n为缓冲区大小
行缓冲:open函数的buffering设置为1
无缓冲:open函数的buffering设置为0

f.open('demo.txt','w',buffering=2048)
f.write('+'*1024) ##文件为空
f.write('+'*1023) ##文件为空
f.write('-'*2)    ##文件有2048个字符

f.open('demo2.txt','w',buffering=1)
f.write('abcd') ##文件为空
f.write('\n')   ##文件有abcd

f.open('demo3.txt','w',buffering=0)
f.write('abcd') ##文件有abcd
f.write('e')   ##文件有abcde

如何将文件映射到内存

场景:
在访问某些二进制文件时,希望能把文件映射到内存中,可以实现随机访问
如果多个进程映射到同一个文件,还能实现进程通信

解决方案:
使用标准库中mmap模块的mmap()函数,它需要一个打开的文件描述符作为参数

import mmmap

f=open('demo.bin','r+b')##打开一个二进制文件
t=f.fileno()##得到一个文件描述符,或者直接使用os模块下的open函数得到
m=mmap.mmap(t,0,access=mmap.ACCESS_WRITE)
##参数分别为文件描述符,映射区域长度(0表示映射整个文件),access表示访问权限
m[0] ##类似数组的索引操作
>'\x00'
m[10:20]##切片操作
m[0]='\x88'##写操作用字节的形式,使用16进制。表面上似修改内存,实际上文件被改变了

m=mmap.mmap(t,mmap.PAGESIZE*8,access=mmap.ACCESS_WRITE,offset=mmap.PAGESIZE*4)
##offset可以指定映射文件的某一区域,但必须以一个内存页的大小对齐,内存页大小使用mmap.PAGESIZE获取

如何访问文件的状态

文件的状态例如:
1. 文件的类型(普通文件,目录,符号链接,设备文件……)
2. 文件的访问权限
3. 文件的最后的访问/修改/节点状态更改时间
4. 普通文件的大小

解决方法:
系统调用:标准库中os模块下的三个系统调用stat,fstat,lstat获取文件状态
快捷函数:标准库中os.path下一些函数,使用起来更简洁

import os
##x.txt是a.txt的一个引用
s=os.stat('x.txt') ##得到的是a.txt的文件状态
os.lstat('x.txt') ##和stat只有一个区别,即不跟随符号链接,得到的是x.txt的文件状态
os.fstat(f.fileno())##传入的参数是一个打开的文件描述符

s.st_mode  ##获取文件的类型,得到一个数,需要进行解析
bin(s.st_mode)  ##采用二进制表示

import stat
stat.S_ISDIR(s.st_mode) ##判断是否是个文件夹
stat.S_ISREG(s.st_mode) ##判断是否是个普通文件
s.st_mode & stat.S_IRUSR  ##利用标志位进行宇运算来判断文件用户的读权限,得到大于0的值说明为真
s.st_mode & stat.S_IXSUR ##判断文件用户的执行权限
s.st_atime  ##获取文件最后的访问时间,得到一个描述数字
s.st_mtime  ##获取文件最后的修改时间
import time
time.localtime(s.st_atime) ##得到一个时间对象,描述年月日时分秒等
s.st_size ##得到文件的大小

os.path.isdir('x.txt') ##判断是否是个目录,返回false
os.path.islink('x.txt')  ##判断是否是符号链接,返回True
os.path.isfile('a.txt')  ##判断是否是普通文件
os.path.getatime('a.txt')
os.path.getsize('a.txt')

如何使用临时文件

某项目中,我们采集到1G数据做数据分析,最终只保留分析结果,这样大量的临时数据会消耗大量的内存资源。我们可使用临时文件存储临时数据(外部存储)
临时文件不用命名,且关闭后会自动被删除

解决方法:使用标准库中tempfile下的 TemporaryFile,NamedTemporaryFile

from tempfile import TemporaryFile,NamedTemporaryFile

f=TemporaryFile() ##读写默认二进制,文件系统是找不到这个文件的,只在本进程使用该文件
f.write('abcdf'*10000)
f.seek(0)
f.read(100) ##根据内存,每次读取100字节

ntf=NamedTemporaryFile()  ##文件系统找得到这个文件,关闭后自动删除掉,可以多个进程使用该文件
ntf=NamedTemporaryFile(delete=False)  ####关闭后不删除 
ntf.name ##可以找到该文件的目录

如何读写CSV数据

方法:使用标准库中的csv模块,可以使用其中的reader和writer完成csv文件的读写

import csv
f=open('a.csv','rb') ##要使用二进制进行打开
reader=csv.reader(f) ##得到reader迭代器
reader.next()
for r in reader:print r

wf=open('b.csv','wb')
writer=csv.writer(wf)
writer.writerow('66666666') ##写入头部
writer.writerow(reader.next()) ##一边读一边写
wf.flush()  ##而flush()表示强制将缓冲区中的数据发送出去,不必等到缓冲区满.清空缓存

如何读写json数据

在web应用中常用到JSON(JavaScript Object Notation)格式传输数据。例如我们利用百度语音识别服务做语音识别,将本地音频数据post到百度语音识别服务器,服务器响应结果为json字符串

方法:使用标准库中的json模块,其中loads,dumps函数可以完成json文件的读写

##实例应用
import json
import requests

##录音
from record import Record
record = Record(channels=1) ##创建一个单声道的录音实例
audioData = record.record(2)  ##录一个两秒的音频文件
##获取token
from secret import API_KEY,SECRET_KEY ##注册百度开发者账号会给两个KEY,这里的secret是一个自编的类
authUrl = 'http://openapi.baidu.com/oauth/2.0/token?
grant_type=client_credentials&client_id='+API_KEY+'&client_secret='+SECRET_KEY
response = requests.get(authUrl)
res = json.loads(response.content)
token = res['access_token']
##语音识别
cuid='xxxxxxxxxx'
srvUrl='http://vop.baidu.com/server_api'+'?cuid='+cuid+'&token='+token
httpHeader = {'Content-Type' : 'audio/wav;rate=8000'}
response = requests.post(response.content)
text = res['result'][0]

print '\n识别结果'
print text
##json模块使用
import json
l=[1,2,'abc',{'name':'Bob','age':None}]
json.dumps(l)##可以将一个python对象转化为json对象
>'[1, 2, "abc", {"name": "Bob", "age": null}]' ##可见None变成null
json.dumps(l,separators=[',',':']) ##把逗号和冒号后面的空格删除掉
json.dumps(l,sort_keys=True) ## 对键进行排序

l2=json.loads('[1, 2, "abc", {"name": "Bob", "age": null}]')

with open('demo.txt','wb') as f:
    json.dump(l,f) ##把l写到json文件当中,dump()对文件操作,load()一样

如何解析简单的xml文档

xml是一种常用的标记性语言,可提供统一的方法来描述应用程序的结构化数据

##举例
##xml是由元素结点构成的树形结构,根节点包括子节点,节点还可以有多个自己的属性
<note>
    <to>George</to>
    <from>John</from>
    <heading>Reminder</heading>
    <body>Don't forget the meeting!</body>
</note>

解决方法:使用标准库中的xml.etree.ElementTree,其中parse函数可以解析xml文档

from xml.etree.ElementTree import parse
f=open('demo.xml')
et=parse(f) ##得到一个ElementTree,即元素树
root=et.getroot() ##得到根节点

root.tag ## 查看标签
root.attrib ##查看属性,得到一个字典
root.text   

for child in root:
    print(child.get('name')) ##get得到元素的属性

root.find('from')  ##根据标签来寻找子元素,返回第一个找到的元素
root.findall('from')   ##返回所有结果,为列表
root.iterfind('from')  ##返回一个可迭代对象
##find只能找root下的直接子元素,其他不行

root.iter()  ##当前节点下所有子元素,为一个迭代器
root.iter(‘rank')  ##递归去寻找所有标签为rank的节点

root.findall('from/*') ##匹配from下的所有子节点
root.findall('.//from')  ##匹配所有层次下的子节点
root.findall('from/..')  ##找到所有from节点的父亲节点
root.findall('country[@name="singapore"]') ##找到节点属性值为Singapore的节点
root.findall('country[rank]') ##找到节点包含子节点rank
root.findall('country[2]')  ##返回第2个结果

如何构建xml文档

解决方案:使用标准库中的xml.etree.ElementTree,构建ElementTree,使用write写入文件

from xml.etree.ElementTree import Element,ElementTree
e=Element('Data')
e.set('name','abc') ##设置节点的属性

from xml.etree.ElementTree import tostring 
##可以看到一个元素属性设置后的字符串形式
tostring(e)
>b'<Data name="abc"/>'
e.text = '123'
tostring(e)
>b'<Data name="abc">123</Data>'
e2 = Element('Row')
e3 = Element('Open')
e3.text='8.80'
e2.append(e3)  ##添加子元素
e.text=None  ##清楚内容
e.append(e2)
tostring(e)
>b'<Data name="abc"><Row><Open>8.80</Open></Row></Data>'
et=ElementTree(e)
et.write('demo.xml') ##写入xml文档
##csv转xml
import csv
from xml.etree.ElementTree import Element,ElementTree 
def csvToXml(fname):
    with open (fname,'rb') as f:
    reader = csv.reader(f)
    headers = reader.next()
    root = Element('Data')
    for row in reader:
        eRow=Element('row')
        root.append(eRow)
        for tag, text in zip(headers,row):
            e = Element(tag)
            e.text = text
            eRow.append(e)
    return ElementTree(root)

et=csvToXml('app.csv')
et.write('app.xml')  ##ElementTree输出的xml没有缩进

def pretty(e,level=0):  ##格式美化,使用递归算法
    if len(e)>0:
        e.text='\n'+'\t'*(level+1)
        for child in e:
            pretty(child,level+1)
        child.tail=child.tail[:-1]
    e.tail='\n'+'\t'*level

如何读写excel文件

方法:使用第三方库xlrd和xlwt,这两个库分别用于excel读和写

import xlrd
book=xlrd.open_workbook('demo.xlsx') ##一个book可以包含多张表
book.sheets() ##返回包含的所有表,是一个列表包含sheet对象
sheet=book.sheet_by_index(0) ##得到索引号为0的表
sheet.nrows ##返回表格的行数
sheet.ncols ##返回表格的列数
cell = sheet.cell(0,0) ##返回坐标为(0,0)的单元格对象
cell.ctype ##查看单元格数据类型,返回一个数字
xlrd.XL_CELL_Text ##返回1,说明数字1表示文本
xlrd.XL_CELL_Number ##返回2,说明数字2表示数值
print(cell.value)  ##获取单元格值,print可以显示unicode表示字符
sheet.row(1) ##获取列表的第2行,返回一个列表包含cell对象
sheet.row_values(1) ##获取第2行单元格值,返回一个列表包含数字或文本
sheet.row_values(11) ##获取第2行从第2个单元格开始的值
sheet.col(1) ##同理column也有相同的方法
sheet.put_cell(1,1,xlrd.XL_CELL_TEXT,'abc') ##创建一个第2行第2列文本类型值为abc的单元格

import xlwt
wbook=xlwt.Workbook() ##创建一个excel文件
wsheet=wbook.add_sheet('sheet1')  ##添加名叫sheet1的表格
wsheet.write(1,1,'abc') ##对表格添加第2行第2列值为abc的单元格,还有个style参数设置格式
wbook.save('output.xlsx')  ##将表格写入到文件中
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值