使用with语句来自动调用f.close()、try...finally语句、file-like Object、字符编码
1.1给出规格化得地址字符串,这些字符串是经过转义的能直接在代码里使用的字符串
import os
>>>os.path.join('user','bin','spam') #可以看做为连接,值得注意的是,不要认为只能这样来连接单个
'user\\bin\\spam' #运行结果
>>>for fileName in os.listdir(path):
totalSize=os.path.getsize(os.path.join(path,fileName))+totalSize
#使用os.path.join()来连接
1.2当前工作目录 os.getcwd() 与 os.chdir(parameter)
1 >>>import os
2 >>>os.getcwd() #取得当前工作路径的字符串
3 'C:\\Python3'
4 >>>os.chdir('C:\\Windows\\System32') #改变工作路径为传入的字符#串
5 #若传入路径不存在,显示FileNotFoundError错误
6 >>>os.getcwd()
7 'C:\\Windows\\System32'
1.3绝对路径与相对路径
这个没什么好说的,就是需要注意下逻辑层次是从当前目录出发的
1.4创建新文件夹 os.makedirs(parameter)
方法执行成功后,会创建所有必要的中间文件夹
1.5处理绝对路径与相对路径、寻找从A到B的 os.path.relpath(path,start) 、地址字符串裁切: os.path.basename(path) 、 os.path.dirname(path) 、 os.path.split(path)
1 >>>os.path.abspath('.') #将返回参数的绝对路径字符串
2 ‘C:\\python3’
3 >>>os.path.isabs('.') #参数是绝对路径是返回True,否则False
4 False
5
6 >>>os.path.relpath('C:\\Windows','C:\\') #从后者到前者的路径。若是没有提供Start,就把当前目录作为Start
7 ‘Windows’
8
9 >>>path='C:\\Windows\\System32\\calc.exe'
10 >>>os.path.dirname(path) #返回一个包含最后一个斜杠之前内容的字符串
11 ‘C:\\Windows\\System32’
12 >>>os.path.basename(path) #返回一个包含最后一个斜杠之后内容的字符串
13 ‘calc.exe’
os.path.split(path)来获得这两个字符串的元组
1 >>>path='C:\\Windows\\System32\\calc.exe'
2 >>>os.path.split(path)
3 ('C:\\Windows\\System32','calc.exe')
os.path.dirname(path) os.path.basename(path)
1 >>>(os.path.dirname(path),os.path.basename(path))
2 ('C:\\Windows\\System32','calc.exe')
os.path.split(path) 并不能接受一个文件路径并返回每个文件夹的字符串的列表。假如你想要实现这样的功能,可以使用 split() 字符串方法,并根据 os.path.sep 中的字符串进行分割,即将变量: os.path.sep
1 >>>path='C:\\Windows\\System32\\calc.exe'
2 path.split(os.path.sep) #spilt()方法将返回一个列表,包含该路径的所有部分,如果向他传递os.path.sep,就能在所有操作平台上工作
3 ['C:','Windows','System32','calc.exe']
1.7查看文件大小和文件夹内容
1 >>>os.path.getsize('C:\\Windows\\System32\\calc.exe')
2 776192
3 >>>os.listdir('C:\\Windows\\System32') #返回的是所提供的文件夹里所有文件名的字符串 ********注意这个在os里,不是os.path里
4 ['1232049.cpx',
5 --snip---
6 '2398r09w.dll']
示例:
1 >>>totalSize=0
2 >>>path=os.getcwd()
3 >>>for fileName in os.listdir(path):
4 totalSize=os.path.getsize(os.path.join(path,fileName))+totalSize
5 #使用os.path.join()来连接
6 '24324234'
1.8 检查路径有效性
1 >>>os.path.exists('C:\\Windows') #若指定文件夹存在
2 True
3 >>>os.path.isdir('C:\\Windows\\System32') #若指定的参数存在,且是一个文件
4 True
5 >>>os.path.isfile('C:\\Windows\\System32') #若指定的参数存在并且是一个文件夹
6 False
2文件读写过程
适用于纯文本文件(即只包含基本文字字符,不包含字体、大小和颜色信息),关于二进制文件的先不做讨论,只需要知道,python中有很多模块,这些模块,使得对二进制文件的处理变得更加容易。这里我们以shelve模块为例
1.1读写文件
python中,读写文件有3个步骤:
1.调用open(parameter)函数,返回一个File对象。如果文件不存在,会创建
2.调用File对象的read()、readlines()或write()方法。
3.调用File对象的close()方法,关闭该文件。文件使用完毕后必须关闭,因为文件对象会占用操作系统的资源,并且操作系统同一时间能打开的文件数量也是有限的:
4.见补充
1 >>>path='C:\\Windows\\System32'
2 >>>helloFile=open(path)
3 >>>helloContent=helloFile.read() #read()方法返回一个大字符串
4 >>>helloContent
5 'Hello World\nHello World'
6 >>>helloContent=helloFile.readlines() #readlines()方法返回一个字符串的列表,每个字符串值都已一个换行字符'\n’结束
7 >>>helloContent
8 ['Hello Content\n','Hello Content\n']
读模式、写模式、添加模式
是以传给open(parameter1,parameter2)的parameter2参数来区分的
open() 的更多信息:点击
>>>baconFile=open('bacon.txt','w') #w代表写模式,会将原有的全部清除
>>>baconFile.write('Hello world!\n') #返回写入字符的个数
13
>>>baconFile.close()
>>>baconFile=open('bacon.txt','a') #a代表添加模式
>>>baconFile.write('Bacon is not a vegetable.') #返回写入字符的个数
25
关于写模式
你可以反复调用 write() 来写入文件,但是务必要调用 f.close() 来关闭文件。当我们写文件时,操作系统往往不会立刻把数据写入磁盘,而是放到内存缓存起来,空闲的时候再慢慢写入。只有调用 close() 方法时,操作系统才保证把没有写入的数据全部写入磁盘。忘记调用 close() 的后果是数据可能只写了一部分到磁盘,剩下的丢失了。所以,还是用 with
with open('/Users/michael/test.txt', 'w') as f:
f.write('Hello, world!')
'w'和‘a’模式的区别,前者会直接覆盖,后者会向已有文件追加内容
open() 函数传入 encoding
在python中使用多行字符串写入
def main():
filename='instance.py'
path=os.path.abspath('.')
code='''print('dir -l1')
s
a
'''
pass
#结果
print('dir -l1')
s
a
3用shelve模块保存变量及删除Shelve键值对
利用shelve模块,可以将python程序中的变量保存到二进制的shelf文件中。
>>>import shelve
>>>shelfFile=shelve.open('mydata') #open()方法传入的是文件名,返回的值保存在变量‘shelfFile’中 *********若mydata不存在,会创建一个
>>>cats=['Zophie','Pooka','Simon']
>>>shelfFile['cats']=cats #这个变量的值是cats(后),键也是cats(前)。键和值相互关联,就像是一个字典一样。cats(后)又被称为shelf值,这个值可以死列表(如上)
>>>shelfFile.close()
稍后可以使用shelve模块,重新打开这些文件并取出数据。不比选择读模式或者写模式,因为他们既能读,又能写
>>> shelfFile=shelve.open('mydata')
>>> type(shelveFile)
<class 'shelve.DbfilenameShelf'>
>>> shelfFile['cats']
['Zophie', 'Pooka', 'Simon']
>>>shelfFile.close()
shelve的keys()与values()方法 **********要记得是keys()不是key()
shelfFile=shelve.open('mydata')
>>> list(shelfFile.keys()) #这些方法返回类似列表的值,而不是真正列表,所以应该将他们传递给list()函数,取得列表的形式
['cats']
>>> list(shelfFile.values())
[['Zophie', 'Pooka', 'Simon']]
>>> shelfFile.close()
删除shelve中的键值对
del shelfFile['cats']
items()
>>> for items in mcbShelve.items():
items
('test', " and sys.argv[1].lower=='save'")
4用pprint.pformat()函数保存变量
pprint.pprint()函数将列表或字典中的内容漂亮打印到屏幕,而 pprint.pformat()
>>> import pprint
>>> cats=[{'doec': 'chubby', 'name': 'Zophie'}, {'dese': 'fluffy', 'name': 'pooka'}]
>>> pprint.pformat(cats)
"[{'doec': 'chubby', 'name': 'Zophie'}, {'dese': 'fluffy', 'name': 'pooka'}]"
>>> fileObj=open('myCats.py','w')
>>> fileObj.write('cats='+pprint.pformat(cats)+'\n') #这样保存
81
>>> fileObj.close()
可以导入自己创建的.py文件
>>> import myCats
>>> myCats.cats
[{'doec': 'chubby', 'name': 'Zophie'}, {'dese': 'fluffy', 'name': 'pooka'}]
>>> myCats.cats[0]
{'doec': 'chubby', 'name': 'Zophie'}
虽然创建一个.py文件能让任何人都能用一个简单的文本编辑器读取和修改文件的内容,但是用shelve模块来保存数据,是将变量保存到文件的最佳方式。因为只有基本数据类型:整形、浮点型、字符串、列表和字典,可以作为简单文本写入一个文件。
四、字符编码
要读取非UTF-8编码的文本文件,需要给 open() 函数传入 encoding
遇到有些编码不规范的文件,你可能会遇到 UnicodeDecodeError ,因为在文本文件中可能夹杂了一些非法编码的字符。遇到这种情况, open() 函数还接收一个 errors
>>> f = open('/Users/michael/gbk.txt', 'r', encoding='gbk', errors='ignore')
更多errors参数:http://www.runoob.com/python/att-string-encode.html
五、补充
IOError ,而一旦出错,后面的 f.close 就不会调用,所以为了保证无论是否出错都能够调用 f.close() ,我们使用 try...finally
try:
f=open('C:/Systems/test.txt','r')
print(f.read())
finally:
if f:
f.close()
with...as 语句,python引入了with语句来帮我们自动调用 close()
with open('C:/Systems/test.txt','r') as f:
print(f.read())
read() 方法会一次读取全部文件,假如文件特别大,超出了内存的容量,那么内存就爆了,我们可以使用 read(size) 方法来帮助我们一次读取size大小的文件。另外,还可以调用 readline() 方法, readlines()
file-like object
open() 返回的这种有个 read() 方法的对象,在Python中统称为file-like Object。除了file外,还可以是内存的字节流,网络流,自定义流等等。file-like Object不要求从特定类继承,只要写个 read() 方法就行。 StringIO
二进制文件
直接以默认的方式调用open(),打开的是文本文件,并且是utf-8编码的,若是需要打开二进制文件(如图片、视频)需要向open()传入rb参数
>>> f = open('/Users/michael/test.jpg', 'rb')
>>> f.read()
b'\xff\xd8\xff\xe1\x00\x18Exif\x00\x00...' # 十六进制表示的字节
打开非utf-8编码文件:
向open()传入encoding参数
>>> f = open('/Users/michael/gbk.txt', 'r', encoding='gbk')
>>> f.read()
'测试'
使用errors参数定义遇到错误时的处理方式,比如遇到编码不规范的文件,则会出现UnicodeDecodeError错误
>>> f = open('/Users/michael/gbk.txt', 'r', encoding='gbk', errors='ignore')