Python 学习 ---> 文件操作 (os、shutil、pathlib)、序列化

参考 :http://www.cnblogs.com/nulige/archive/2016/12/06/6037752.html

在Python 3.4之前,涉及路径相关操作,都用 os 模块解决,尤其是 os.path 这个子模块非常有用。在 Python 3.4 之后,pathlib 成为标准库模块,其使用面向对象的编程方式来表示文件系统路径,丰富了路径处理的方法。

pathlib 官网文档:https://docs.python.org/zh-cn/3.11/library/pathlib.html

1、Python 文件操作

Python2 使用内建函数 file 进行文件操作。Python3 移除了 file 函数,使用 open 函数替代。

open(file, mode='r', buffering=-1, encoding=None, errors=None, newline=None, closefd=True, opener=None)

readreadline write 方法来恰当地读写文件。对文件的读写能力依赖于你在打开文件时指定的模式。最后,当你完成对文件的操作的时候,你调用 close 方法来告诉 Python 我们完成了对文件的使用。

读文件

以读方式打开文件后可以调用这三个函数:read()、readline()、readlines()

read() 和 readlines() 默认都是获取文件的所有内容。但是read()返回一个String类型对象,元素是一个Char。readlines() 返回一个List类型对象,元素是一个Sting。而 readline() 获取文件的一行内容,返回是一个String。

1.open
    使用open打开文件后一定要记得调用文件对象的close()方法。比如可以用try/finally语句来确保最后能关闭文件。
    file_object = open('thefile.txt')
    try:
         all_the_text = file_object.read( )
    finally:
         file_object.close( )
    注:不能把open语句放在try块里,因为当打开文件出现异常时,文件对象file_object无法执行close()方法。

2.读文件
    读文本文件
    input = open('data', 'r')
    #第二个参数默认为r
    input = open('data')
    
    读二进制文件
    input = open('data', 'rb')
    
    读取所有内容
    file_object = open('thefile.txt')
    try:
        all_the_text = file_object.read( )
    finally:
        file_object.close( )
    
    读固定字节
    file_object = open('abinfile', 'rb')
    try:
        while True:
            chunk = file_object.read(100)
            if not chunk:
                break
            do_something_with(chunk)
    finally:
        file_object.close( )
    
    读每行
    list_of_all_the_lines = file_object.readlines( )
    如果文件是文本文件,还可以直接遍历文件对象获取每行:
    for line in file_object:
        process line
    
3.写文件
    写文本文件
    output = open('data', 'w')
     
    写二进制文件
    output = open('data', 'wb')
     
    追加写文件
    output = open('data', 'w+')
     
    写数据
    file_object = open('thefile.txt', 'w')
    file_object.write(all_the_text)
    file_object.close( )
     
    写入多行
    file_object.writelines(list_of_text_strings)
    
    注意,调用writelines写入多行在性能上会比使用write一次性写入要高。

写文件

注意:调用 write()、writeline() 时,文件原有的内容会被清空,因为文件指针初始指向文件的首行首个字母,而进行写操作实质就是在文件指针指向的位置开始写入内容。

pwd = open('fileOperation.txt','w')
pwd.write('My name is JMilk')
pwd.flush()
pwd.write('My name is chocolate')
pwd.flush()
pwd.write('123')
pwd.write('456')
pwd.close()

结果:

My name is JMilkMy name is chocolate123456

修改指定行的内容:

cfg = open(cfgUrl,'r+')
cfgFile = cfg.readlines()
cfgFile[lineNum] = cfgStr

cfg = open(cfgUrl,'w+')
cfg.writelines(cfgFile)
cfg.flush()   #刷新内存的缓存区,即将缓存区中的内容写入到磁盘,但不会关闭文件。
cfg.close()

将文件以r+的方式打开,并返回一个对象。对对象的内容进行修改后,再将文件以w+的方式打开,将对象的内容写入到文件中。实现对文件指定行的内容修改。

writelines() 写入多行内容

import os
def write_lines(fileName,content_iterable):
    try:
        pwd = open(fileName,'w')
        pwd.writelines(content_iterable) #传递List类型参数
    finally:
        pwd.close()

if __name__ == '__main__':
    fileName = '/usr/local/src/pyScript/fileOperation.txt'
    li = ['my name is Jmilk'+'\n','My name is chocolate'+'\n']  #定义List时加入换行符
    if os.path.exists(fileName):
        write_lines(fileName,li)
    else:print 'File not exist!'

        
结果:
my name is Jmilk
My name is chocolate 

write()和writelines()的区别

从上面两个例子中可以看出,write()接受的是String类型参数,所以可以在()中对实参进行修改加入’\n’。而writelines()接受的是iterable类型参数,并且iteraber对象的元素需要为String类型,只能在定义iterable的时候加入’\n’。在写入多行内容时writelines()会比write()更有效率。再一次反映 数据结构决定了对象操作这一句话,所以对数据结构的理解是非常重要的。python数据结构,请参考:Python基本数据类型_范桂飓的博客-CSDN博客_python 引用数据类型

使用 with 语句

可以同时对多个文件同时操作,当with代码块执行完毕时,会自动关闭文件释放内存资源,不用再主动调用 f.close() 。

num = 0
with open('file','r') as f1,open('file2','w',encoding='utf8') as f2:
    for line in f1:
        num += 1
        if num == 5:
            line = ''.join([line.strip(),'羊小羚'])
        f2.write(line)

示例:文件的 读、写

  • open 是一个内建函数,用来打开文件。
  • 模式可以为读模式('r')、写模式('w')或追加模式('a')。还有很多的模式可以使用,可以使用 help(open) 来了解。
  • encoding 指定编码格式

tip = '''
Python2 中 file 是内建函数
Python3 中 移除了 file 函数,使用 open 函数替代
'''
f = open('poem.txt', 'w', encoding='utf-8')
f.write(tip)
f.close()

f = open('poem.txt', encoding='utf-8')
while True:
    line = f.readline()
    if len(line) == 0:
        break
    print(line, end='')
f.close()

示例首先用写模式打开文件,然后使用 open 的 write 方法来写文件,最后我们用 close 关闭这个文件。

接下来,我们再一次打开同一个文件来读文件。如果我们没有指定模式,读模式会作为默认的模式。在一个循环中,我们使用 readline 方法读文件的每一行。这个方法返回包括行末换行符的一个完整行。所以,当一个空的 字符串被返回的时候,即表示文件末已经到达了,于是我们停止循环。
注意,因为从文件读到的内容已经以换行符结尾,所以我们在 print 语句上使用 end 来消除自动换行。最后,我们用 close 关闭这个文件。

将标准输出重定向写入到指定文件

系统标准输入、输出、Err本质是一个类文件对象。重定向即: sys.stdout = fileObject_write 

#!/usr/bin/env python
#Filename:stdoTest.py
#coding=utf8
import sys


fristOut = sys.stdout  #备份初始的输出文件对象
print type(fristOut)

logOut = open('/usr/local/src/pyScript/out.log','w') 
sys.stdout = logOut  #重定向输出到新的文件对象
print 'Test stdout.'  #重定向后,不会打印到屏幕

logOut.close()   #关闭open()打开的文件对象
sys.stdout = fristOut  #还原输出文件对象

文件指针

文件指针:当使用open()函数打开一个文件并返回一个文件对象后,在文件对象中会存放着当前”光标”在文件中的位置,对文件进行的读、写、截断操作都是基于文件指针,并从文件指针+1开始进行的操作。。这个位置称为文件指针(从文件头部开始计算的字节数),与C语言额指针概念相似,实质是文件中位置的标识。大部分的文件操作都是基于文件指针来实现的。注意:当对文件进行了读、写操作后都会改变文件指针的值。

  • tell():查询文件中光标位置
  • seek():光标定位
  • tell() 获取当前文件指针(位置)

pwd = open('fileOperation.txt','rw+')
pwd.tell()


结果:
0        // 因为新打开的文件,文件指针指向文件开头位置

seek() 转移文件指针

seek(…) 
seek(offset[, whence]) -> None. Move to new file position. 

可以接收偏移量和选项作为参数,返回None。 
当whence==0时,将文件指针从文件头部转移到”偏移量”指定的字符处。 
当whence==1时,将文件指针从文件的当前位置往后转移”偏移量”指定的字符数。 
当whence==2时,将文件指针从文件尾部向前移动”偏移量”指定的字符数。 

使用示例:

f = open('file','r')
print(f.tell())  #光标默认在起始位置
f.seek(10)    #把光标定位到第10个字符之后
print(f.tell())  #输出10
f.close()
----------------------
f = open('file','w')
print(f.tell())  #先清空内容,光标回到0位置
f.seek(10)    
print(f.tell())
f.close()
----------------------
f = open('file','a')
print(f.tell())  #光标默认在最后位置
f.write('你好 世界')
print(f.tell())  #光标向后9个字符,仍在最后位置
f.close()

flush()

同步将数据从缓存转移到磁盘

示例,实现进度条功能

import sys,time  
for i in range(40):
    sys.stdout.write('*')
    sys.stdout.flush()  
    time.sleep(0.2)

if __name__ == '__main__':
    pass

    
# 下面代码也能够实现相同的功能
import time 
for i in range(40):
    print('*',end='',flush=True) #print中的flush参数
    time.sleep(0.2)

truncate() 截断文件

不能在r模式下执行。w模式下,已经清空所有数据,使用truncate没有任何意义。a模式下,截断指定位置后的内容。

truncate(…) 
truncate([size]) -> None. Truncate the file to at most size bytes. 
Size defaults to the current file position, as returned by tell(). 

默认从文件指针指向的位置开始截断文件内容,也可以通过传递int参数n来指定截断的起始位置,即改变文件指针的位置。
从文件指针指向的位置n开始,之后的文件内容(不包含n)全部删除,以可修改mode打开的文件可以使用此方法。

f = open('file','a')
f.truncate(6) #只显示6个字节的内容(6个英文字符或三个汉字),后面的内容被清空。

光标位置总结

一个汉字两个字节,涉及光标位置的方法有4个:readtellseektruncate

#--------------------------光标总结head-----------------------------------
f = open('file','r')
print(f.read(6)) #6个字符
print(f.tell())  #位置12字节,一个汉字两个字节
f.close()
 
f = open('file','r')
f.seek(6)      #6个字节
print(f.tell())
f.close()
 
f = open('file','a')
print(f.tell())  #光标默认在最后位置
f.write('你好 世界')
print(f.tell())  #光标向后9个字节,一个汉字两个字节,仍在最后位置 182-->191
f.close()
 
f = open('file','a',encoding='utf-8')
print(f.truncate(6)) #由于需要光标定位位置,所以也是字节。只显示6个字节的内容(6个英文字母或三个汉字,一个汉字两个字节),后面的内容被清空。
f.close()
#-----------------------------光标总结end---------------------------------

一个综合例子:truncate()+tell()+seek()

In [8]: %cat fileOperation.txt
0123456789

In [9]: pwd = open('fileOperation.txt','rw+')

In [10]: pwd.tell()
Out[10]: 0

In [11]: pwd.seek(5)

In [12]: pwd.tell()
Out[12]: 5

In [13]: pwd.truncate()

In [14]: pwd.close()

In [15]: %cat fileOperation.txt
01234

2、文件、目录 操作

os.path.exists(test_dir)
os.path.exists(test_file.txt)
os.path.isfile("test-data")

相关模块:pathlib、os、shutil、

pathlib --- 面向对象的文件系统路径

pathlib 模块在 Python3 版本中是内建模块

pathlib 官方文档:https://docs.python.org/zh-cn/3/library/pathlib.html

你应该使用 pathlib 替代 os.path:https://zhuanlan.zhihu.com/p/87940289

path = pathlib.Path("path/file")
path.exist()
path.is_file()

Python 路径操作模块 pathlib,看这篇就够了!:https://zhuanlan.zhihu.com/p/475661402

os 模块

os 模块 ( 操作系统:Operating system  )是 Python 标准库中的一个用于访问操作系统功能的模块,使用OS模块中提供的接口,可以实现跨平台访问,用于提供系统级别的操作。os.getcwd()、os.path.abspath(__file__)、os.path.realpath(__file__)

sys 模块 主要是用于提供对 python 解释器相关的操作。sys.path 是 Python 会去寻找模块的搜索路径列表。sys.path[0] 和 sys.argv[0] 是一回事,因为Python 会自动把 sys.argv[0] 加入sys.path。

如果你在 C:\test 目录下执行:python dir_test\getpath.py,

os.getcwd() 会输出“C:\test”

sys.path[0] 会输出“C:\test\dir_test”。

示例

#!/bin/env python
# -*- encoding=utf8 -*-

import os, sys

if __name__ == "__main__":
    # __file__是当前执行的文件
    print(f"__file__={__file__}")
    # 获取当前文件__file__的路径
    print(f"os.path.realpath(__file__)={os.path.realpath(__file__)}")
    # 获取当前文件__file__的所在目录
    print(f"os.path.dirname(os.path.realpath(__file__))={os.path.dirname(os.path.realpath(__file__))}")
    # 获取当前文件__file__的所在目录
    print(f"os.path.split(os.path.realpath(__file__))={os.path.split(os.path.realpath(__file__))[0]}")
    print(f"os.path.abspath(__file__)={os.path.abspath(__file__)}")
    print(f"os.getcwd()={os.getcwd()}")
    print(f"sys.path[0]={sys.path[0]}")
    print(f"sys.argv[0]={sys.argv[0]}")

os.sep 可以取代操作系统特定的路径分隔符。windows下为 '\\'
os.name 字符串指示你正在使用的平台。比如对于Windows,它是'nt',而对于Linux/Unix用户,它是 'posix'
os.getcwd() 函数得到当前工作目录,即当前Python脚本工作的目录路径
os.getenv() 获取一个环境变量,如果没有返回none
os.putenv(key, value) 设置一个环境变量值
os.listdir(path) 返回指定目录下的所有文件和目录名
os.remove(path) 函数用来删除一个文件
os.system(command) 函数用来运行shell命令
os.linesep 字符串给出当前平台使用的行终止符。例如,Windows使用 '\r\n',Linux使用 '\n' 而Mac使用 '\r'
os.path.split(path)  函数返回一个路径的目录名和文件名
os.path.isfile() 和os.path.isdir()函数分别检验给出的路径是一个文件还是目录
os.path.exists() 函数用来检验给出的路径是否真地存在
os.curdir  返回当前目录 ('.')
os.mkdir(path) 创建一个目录
os.makedirs(path) 递归的创建目录
os.chdir(dirname) 改变工作目录到dirname    
os.path.getsize(name) 获得文件大小,如果name是目录返回0L
os.path.abspath(name) 获得绝对路径
os.path.normpath(path) 规范path字符串形式
os.path.splitext()  分离文件名与扩展名
os.path.join(path,name) 连接目录与文件名或目录
os.path.basename(path) 返回文件名
os.path.dirname(path) 返回文件路径
os.walk(top,topdown=True,οnerrοr=None)  遍历迭代目录

os.rename(src, dst)  重命名file或者directory src到dst 
如果dst是一个存在的directory, 将抛出OSError. 在Unix, 如果dst存在且是一个file, 如果用户
有权限的话,它将被安静的替换. 操作将会失败在某些Unix 中如果src和dst在不同的文件系统中. 
如果成功, 这命名操作将会是一个原子操作 (这是POSIX 需要). 
在 Windows上, 如果dst已经存在, 将抛出OSError,即使它是一个文件. 在unix,Windows中有效。

os.renames(old, new) 递归重命名文件夹或者文件。像rename()

1.得到当前工作目录,即当前Python脚本工作的目录路径: os.getcwd()        
2.返回指定目录下的所有文件和目录名:                 os.listdir()
3.函数用来删除一个文件:                   os.remove()
4.删除多个目录:                          os.removedirs(r“c:\python”)
5.检验给出的路径是否是一个文件:          os.path.isfile()
6.检验给出的路径是否是一个目录:          os.path.isdir()
7.判断是否是绝对路径:                    os.path.isabs()
8.检验给出的路径是否真地存:               os.path.exists()
9.返回一个路径的目录名和文件名: os.path.split()     eg os.path.split('/home/swaroop/byte/code/poem.txt') 
                                                    结果:('/home/swaroop/byte/code', 'poem.txt') 
10.分离扩展名:       os.path.splitext()
11.获取路径名:       os.path.dirname()
12.获取文件名:       os.path.basename()
13.运行shell命令:     os.system()
14.读取和设置环境变量:os.getenv() 与os.putenv()
15.给出当前平台使用的行终止符:    os.linesep    Windows使用'\r\n',Linux使用'\n'而Mac使用'\r'
16.指示你正在使用的平台:         os.name       对于Windows,它是'nt',而对于Linux/Unix用户,它是'posix'
17.重命名:          os.rename(old, new)
18.创建多级目录:    os.makedirs(r“c:\python\test”)
19.创建单个目录:    os.mkdir(“test”)
20.获取文件属性:    os.stat(file)
21.修改文件权限与时间戳:os.chmod(file)
22.终止当前进程:        os.exit()
23.获取文件大小:        os.path.getsize(filename)

shutil 模块

shutil.copyfile( src, dst) 从源src复制到dst中去。当然前提是目标地址是具备可写权限。
                           抛出的异常信息为IOException. 如果当前的dst已存在的话就会被覆盖掉
shutil.move( src, dst)  移动文件或重命名
shutil.copymode( src, dst) 只是会复制其权限其他的东西是不会被复制的
shutil.copystat( src, dst) 复制权限、最后访问时间、最后修改时间
shutil.copy( src, dst)  复制一个文件到一个文件或一个目录
shutil.copy2( src, dst)  在copy上的基础上再复制文件最后访问时间与修改时间也复制过来了,
                         类似于cp –p的东西
shutil.copy2( src, dst)  如果两个位置的文件系统是一样的话相当于是rename操作,只是改名;
                         如果是不在相同的文件系统的话就是做move操作
shutil.copytree( olddir, newdir, True/Flase)
           把olddir拷贝一份newdir,如果第3个参数是True,则复制目录时将保持文件夹下的符号连接,
           如果第3个参数是False,则将在复制的目录下生成物理副本来替代符号连接
shutil.rmtree( src ) 递归删除一个目录以及目录内的所有内容

文件 操作

关于 open 模式:

r: 只读模式,文件必须存在
w: 以写方式打开,
a: 以追加模式打开 (从 EOF 开始, 必要时创建新文件)
r+:以读写模式打开。            读写模式,光标默认在起始位置,当需要写入的时候,光标自动移到最后
w+:以读写模式打开 (参见 w )    写读模式,先清空原内容,再写入,也能够读取
a+:以读写模式打开 (参见 a )    追加读模式,光标默认在最后位置,直接写入,也能够读取。
rb:以二进制读模式打开
wb:以二进制写模式打开 (参见 w )
ab:以二进制追加模式打开 (参见 a )
rb+:以二进制读写模式打开 (参见 r+ )
wb+:以二进制读写模式打开 (参见 w+ )
ab+:以二进制读写模式打开 (参见 a+ )

文件操作:

os.mknod("test.txt")        # 创建空文件
fp = open("test.txt", 'w')  # 直接打开一个文件,如果文件不存在则创建文件

fp.read([size])             # size为读取的长度,以byte为单位
fp.readline([size])         # 读一行,如果定义了size,有可能返回的只是一行的一部分
fp.readlines([size])        # 把文件每一行作为一个list的一个成员,并返回这个list。其实它的内部是通过循环调用readline()来实现的。
                              如果提供size参数,size是表示读取内容的总长,也就是说可能只读到文件的一部分。
fp.write(str)               # 把str写到文件中,write()并不会在str后加上一个换行符
fp.writelines(seq)          # 把seq的内容全部写到文件中(多行一次性写入)。这个函数也只是忠实地写入,不会在每行后面加上任何东西。
fp.close()                  # 关闭文件。python会在一个文件不用后自动关闭文件,不过这一功能没有保证,最好还是养成自己关闭的习惯。  
                            # 如果一个文件在关闭后还对其进行操作会产生ValueError
fp.flush()                  # 把缓冲区的内容写入硬盘
fp.fileno()                 # 返回一个长整型的”文件标签“
fp.isatty()                 # 文件是否是一个终端设备文件(unix系统中的)
fp.tell()                   # 返回文件操作标记的当前位置,以文件的开头为原点
fp.next()                   # 返回下一行,并将文件指针移到下一行。把一个file用于for … in file这样的语句时,就是调用next()函数来实现遍历的。
fp.seek(offset[,whence])    # 将文件打操作标记移到offset的位置。这个offset一般是相对于文件的开头来计算的,一般为正数。
                               如果提供whence参数就不一定了,whence为 0 表示从头开始计算,1 表示以当前位置为原点计算。
                               2 表示以文件末尾为原点进行计算。
                               注意:如果文件以a或a+的模式打开,每次进行写操作时,文件操作标记会自动返回到文件末尾。
fp.truncate([size])         # 把文件裁成规定的大小,默认的是裁到当前文件操作标记的位置。
                              如果size比文件的大小还要大,依据系统的不同可能是不改变文件,
                              也可能是用0把文件补到相应的大小,也可能是随机内容加上去。

​注意:把两个路径合成一个时,不要直接拼字符串,而要通过 os.path.join(part1,part2)函数,这样可以正确处理不同操作系统的路径分隔符。在linux/Unix/Mac下,os.path.join()返回这样的字符串: part1/part2。而Windows下会返回这样的字符串: part1\part2

import os
import shutil

file_dir = "D:\\Python_os\\os"                          # 注意 \\ ;windows 下是这么表示的;Linux 和 Mac 是 /
file_name = "test.txt"
file_abs = os.path.join(file_dir, file_name)            # os.path.join(...) 表示路径链接


'''判断路径或文件'''
print (1,os.path.isabs(file_dir))                       # 判断是否绝对路径
print (2,os.path.isabs(file_name))                        
print (3,os.path.isabs(file_abs))                        
print (4,os.path.exists(file_abs))                      # 判断是否真实存在
print (5,os.path.exists(os.path.join(file_dir,"xxx")))                
print (6,os.path.isdir(file_dir))                       # 判断是否是个目录
print (7,os.path.isdir(file_abs))        
print (8,os.path.isfile(file_dir))                      # 判断是否是个文件
print (9,os.path.isfile(file_abs))   

复制、移动文件夹/文件。须使用 shutil 模块,引入 import shutil 

shutil.copyfile("old","new")  # 复制文件,都只能是文件
shutil.copytree("old","new") # 复制文件夹,都只能是目录,且new必须不存在
shutil.copy("old","new")   # 复制文件/文件夹,复制 old 为 new(new是文件,若不存在,即新建),
                              # 复制 old 为至 new 文件夹(文件夹已存在)
shutil.move("old","new")    # 移动文件/文件夹至 new 文件夹中

import os
import shutil

file_dir = "D:\\Python_shutil"
os.chdir(file_dir)
shutil.copyfile("test_org.txt","test_copy.txt")        # copy test_org.txt 为 test_copy.txt 若存在,则覆盖
shutil.copyfile("test_org.txt","test1.txt")            # 存在,覆盖
shutil.copytree("test_org","test_copytree")            # copy test_org 为 test_copytree(不存在的新目录)
shutil.copy("test_org.txt","test_copy1.txt")           # 同 copyfile
shutil.copy("test_org.txt","test_copy")                # 将文件 copy 至 目标文件夹中(须存在)
shutil.copy("test_org.txt","test_xxx")                 # 将文件 copy 至 目标文件(该文件可不存在,注意类型!)
print os.listdir(os.getcwd())
shutil.move("test_org.txt","test_move")                # 将文件 move 至 目标文件夹中
shutil.move("test_org","test_move")                    # 将文件夹 move 至 目标文件夹中
print os.listdir(os.getcwd())

 遍历文件

os.walk() 用于通过在目录树中游走,并输出在目录中的文件名,可以向上或者向下游走。

os.walk(top[, topdown=True[, οnerrοr=None[, followlinks=False]]])

参数

  • top -- 是你所要遍历的目录的地址, 返回的是一个三元组(root,dirs,files)。
            root 所指的是当前正在遍历的这个文件夹的本身的地址
            dirs 是一个 list ,内容是该文件夹中所有的目录的名字(不包括子目录)
            files 同样是 list , 内容是该文件夹中所有的文件(不包括子目录)
  • topdown --可选,为 True,则优先遍历 top 目录,否则优先遍历 top 的子目录(默认为开启)。如果 topdown 参数为 True,walk 会遍历top文件夹,与top 文件夹中每一个子目录。
  • onerror -- 可选,需要一个 callable 对象,当 walk 需要异常时,会调用。
  • followlinks -- 可选,如果为 True,则会遍历目录下的快捷方式(linux 下是软连接 symbolic link )实际所指的目录(默认关闭),如果为 False,则优先遍历 top 的子目录。

返回值

  • 生成器

示例:

import os
for root, dirs, files in os.walk(".", topdown=False):
    for name in files:
        print(os.path.join(root, name))
    for name in dirs:
        print(os.path.join(root, name))

遍历文件夹

def walkFile(file):
    for root, dirs, files in os.walk(file):

        # root 表示当前正在访问的文件夹路径
        # dirs 表示该文件夹下的子目录名list
        # files 表示该文件夹下的文件list

        # 遍历文件
        for f in files:
            print(os.path.join(root, f))

        # 遍历所有的文件夹
        for d in dirs:
            print(os.path.join(root, d))
import os

root_dir = "d:/" # 指明被遍历的文件夹

# 三个参数:分别返回:1.父目录 2.所有文件夹名字(不含路径) 3.所有文件名字
for parent, dir_names, file_names in os.walk(root_dir):
    for dir_name in dir_names:  # 输出文件夹信息
        print "parent is:" + parent
        print "dirname is" + dir_name

    for file_name in file_names:  # 输出文件信息
        print "parent is:" + parent
        print "filename is:" + file_name
        print "the full name of the file is:" + os.path.join(parent, file_name)  # 输出文件路径

python本身并没有对二进制进行支持,不过提供了一个模块来弥补,就是struct模块。

# python没有二进制类型,但可以存储二进制类型的数据,就是用string字符串类型来存储二进制数据,
# 这也没关系,因为string是以1个字节为单位的。

import struct
a=12.34

#将a变为二进制
bytes=struct.pack('i',a)    #此时bytes就是一个string字符串,字符串按字节同a的二进制存储内容相同。

 

#再进行反操作。现有二进制数据bytes,(其实就是字符串),将它反过来转换成python的数据类型:

a,=struct.unpack('i',bytes)    #注意,unpack返回的是tuple

# 所以如果只有一个变量的话:
bytes=struct.pack('i',a)

# 那么,解码的时候需要这样
a,=struct.unpack('i',bytes) 或者 (a,)=struct.unpack('i',bytes)

#如果直接用a=struct.unpack('i',bytes),那么 a=(12.34,) ,是一个tuple而不是原来的浮点数了。
#如果是由多个数据构成的,可以这样:
a='hello'
b='world!'
c=2
d=45.123
bytes=struct.pack('5s6sif',a,b,c,d)

# 此时的bytes就是二进制形式的数据了,可以直接写入文件比如 binfile.write(bytes)
# 然后,当我们需要时可以再读出来,bytes=binfile.read()
# 再通过struct.unpack()解码成python变量
a,b,c,d=struct.unpack('5s6sif',bytes)

'5s6sif'这个叫做fmt,就是格式化字符串,由数字加字符构成,5s表示占5个字符的字符串,2i,表示2个整数等等,
下面是可用的字符及类型,ctype表示可以与python中的类型一一对应。

目录 操作

1.创建目录
    os.mkdir("file")                   
2.复制文件:
    shutil.copyfile("oldfile","newfile")    #oldfile和newfile都只能是文件
shutil.copy("oldfile","newfile")            #oldfile只能是文件夹,newfile可以是文件,也可以是目标目录
3.复制文件夹:
4.shutil.copytree("olddir","newdir")        #olddir和newdir都只能是目录,且newdir必须不存在
5.重命名文件(目录)
os.rename("oldname","newname")              #文件或目录都是使用这条命令
6.移动文件(目录)
shutil.move("oldpos","newpos")   
7.删除文件
os.remove("file")
8.删除目录
os.rmdir("dir")                             #只能删除空目录
shutil.rmtree("dir")                        #空目录、有内容的目录都可以删
9.转换目录
os.chdir("path")                            #换路径

os.getcwd()     # 获取当前工作目录
os.chdir(...)    # 改变工作目录
os.listdir(...)   # 列出目录下的文件
os.mkdir(...)     # 创建单个目录        注意:创建多级用 os.makedirs()
os.makedirs(...)   # 创建多级目录  

实例

将文件夹下所有图片名称加上 '_fc'

# -*- coding:utf-8 -*-
import re
import os
import time
#str.split(string)分割字符串
#'连接符'.join(list) 将列表组成字符串
def change_name(path):
    global i
    if not os.path.isdir(path) and not os.path.isfile(path):
        return False
    if os.path.isfile(path):
        file_path = os.path.split(path) #分割出目录与文件
        lists = file_path[1].split('.') #分割出文件与文件扩展名
        file_ext = lists[-1] #取出后缀名(列表切片操作)
        img_ext = ['bmp','jpeg','gif','psd','png','jpg']
        if file_ext in img_ext:
            os.rename(path,file_path[0]+'/'+lists[0]+'_fc.'+file_ext)
            i+=1 #注意这里的i是一个陷阱
        #或者
        #img_ext = 'bmp|jpeg|gif|psd|png|jpg'
        #if file_ext in img_ext:
        #    print('ok---'+file_ext)
    elif os.path.isdir(path):
        for x in os.listdir(path):
            change_name(os.path.join(path,x)) #os.path.join()在路径处理上很有用
img_dir = 'D:\\xx\\xx\\images'
img_dir = img_dir.replace('\\','/')
start = time.time()
i = 0
change_name(img_dir)
c = time.time() - start
print('程序运行耗时:%0.2f'%(c))
print('总共处理了 %s 张图片'%(i))

输出结果:
程序运行耗时:0.11
总共处理了 109 张图片

序列化

序列化作用:程序运行中得到了一些字符串,列表,字典等数据 长久的保存下来,方便以后使用,而不是简单的放入内存中关机断电就丢失数据

Python 提供一个标准的模块,称为 pickle。使用它你可以在一个文件中储存 任何Python对象,之后你又可以把它完整无缺地取出来。这被称为 持久的储存对象

python3 的 _pickle 模块详解:https://www.cnblogs.com/ranxf/p/7800179.html

或者使用 pandas 里面的 cPickle:https://blog.csdn.net/sinat_36458870/article/details/73551210

还有另一个模块称为 cPickle,它的功能和 pickle 模块完全相同,只不过它是用C语言编写的,因此要快得多( 比 pickle 快 1000 倍)。你可以使用它们中的任一个,而我们在这里将使用 cPickle 模块。记住,我们把这两个模块都简称为 pickle 模块。

存储与存取

# import cPickle as p  # python2 使用 cPickle 方法
# python3中cPickle模块已经更名为_pickle,所以在python3中导入时可以使用:
import _pickle as p    # python3 使用 cPickle 方法

# import pickle as p

shop_list_file = 'shop_list.data'
# the name of the file where we will store the object

shop_list = ['apple', 'mango', 'carrot']

# Write to the file
f = open(shop_list_file, 'w')
p.dump(shop_list, f)  # dump the object to a file
f.close()

del shop_list  # remove the shop_list

# Read back from the storage
f = open(shop_list_file)
stored_list = p.load(f)
print(stored_list)

# 输出
# $ python
# pickling.py
# ['apple', 'mango', 'carrot']

首先,请注意我们使用了 import..as 语法。这是一种便利方法,以便于我们可以使用更短的模块名称。在这个例子中,它还让我们能够通过简单地改变一行就切换到另一个模块(cPickle或者pickle)!在程序的其余部分的时候,我们简单地把这个模块称为p。为了在文件里储存一个对象,首先以写模式打开一个file对象,然后调用储存器模块的dump函数,把对象储存到打开的文件中。这个过程称为储存 。接下来,我们使用pickle模块的load函数的返回来取回对象。这个过程称为 取储存 。

存储对象(序列化存储)

使用上面的模块,可以实现在文件中对字符串的读写。 然而,有的时候,你可能需要传递其它类型的数据,如list、tuple、dictionary和其它对象。在Python中,你可以使用Pickling来完成。你可以使用Python标准库中的“pickle”模块完成数据转储。
下面,我们来编组一个包含字符串和数字的list:

import pickle

fileHandle = open('pickleFile.txt', 'w')
testList = ['This', 2, 'is', 1, 'a', 0, 'test.']
pickle.dump(testList, fileHandle)
fileHandle.close()


fileHandle = open('pickleFile.txt')
testList = pickle.load(fileHandle)
fileHandle.close()
print testList

存储更加复杂的数据:

import pickle

fileHandle = open('pickleFile.txt', 'w') 
testList = [123, {'Calories': 190}, 'Mr. Anderson', [1, 2, 7]] 
pickle.dump(testList, fileHandle) 
fileHandle.close()


fileHandle = open('pickleFile.txt') 
testList = pickle.load(fileHandle) 
fileHandle.close()

使用Python的“pickle”模块编组确实很简单。众多对象可以通过它来存储到文件中。如果可以的话,“cPickle”同样胜任这个工作。它和“pickle”模块一样,但是速度更快:

import cPickle

fileHandle = open('pickleFile.txt', 'w')
cPickle.dump(1776, fileHandle)
fileHandle.close()

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值