python—文件操做相关模块

python 关于操做文件的相关模块(os,sys,shutil,subprocess,configparser)

 

一:os模块

os模块提供了许多容许你程序与操做系统直接交互的功能html

os.getcwd() 获取当前工做目录,即当前python脚本工做的目录路径
 
os.chdir("dirname")  改变当前脚本工做目录;至关于shell下cd
 
os.curdir  返回当前目录: ('.')
 
os.pardir  获取当前目录的父目录字符串名:('..')
 
os.makedirs('dirname1/dirname2')    可生成多层递归目录
 
os.removedirs('dirname1')    若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推
 
os.mkdir('dirname')    生成单级目录;至关于shell中mkdir dirname
 
os.rmdir('dirname')    删除单级空目录,若目录不为空则没法删除,报错;至关于shell中rmdir dirname
 
os.listdir('dirname')    列出指定目录下的全部文件和子目录,包括隐藏文件,并以列表方式打印
 
os.remove()  删除一个文件
 
os.rename("oldname","newname")  重命名文件/目录
 
os.stat('path/filename')  获取文件/目录信息
 
os.sep    输出操做系统特定的路径分隔符,win下为"\\",Linux下为"/"
 
os.linesep    输出当前平台使用的行终止符,win下为"\t\n",Linux下为"\n"
 
os.pathsep    输出用于分割文件路径的字符串 win下为;,Linux下为:
 
os.name    输出字符串指示当前使用平台。win->'nt'; Linux->'posix'
 
os.system("bash command")  运行shell命令,直接显示
 
os.environ  获取系统环境变量
 
os.path.abspath(path)  返回path规范化的绝对路径
 
os.path.split(path)  将path分割成目录和文件名二元组返回
 
os.path.dirname(path)  返回path的目录。其实就是os.path.split(path)的第一个元素
 
os.path.basename(path)  返回path最后的文件名。如何path以/或\结尾,那么就会返回空值。即         os.path.split(path)的第二个元素
 
os.path.exists(path)  若是path存在,返回True;若是path不存在,返回False
 
os.path.isabs(path)  若是path是绝对路径,返回True
 
os.path.isfile(path)  若是path是一个存在的文件,返回True。不然返回False
 
os.path.isdir(path)  若是path是一个存在的目录,则返回True。不然返回False
 
os.path.join(path1[, path2[, ...]])  将多个路径组合后返回,第一个绝对路径以前的参数将被忽略
 
os.path.getatime(path)  返回path所指向的文件或者目录的最后存取时间
 
os.path.getmtime(path)  返回path所指向的文件或者目录的最后修改时间

  

  

1,当前路径及路径下的文件python

  • os.getcwd():查看当前所在路径。
  • os.listdir(path):列举目录下的全部文件。返回的是列表类型。
>>> import os
>>> os.getcwd()
'D:\\pythontest\\ostest'
>>> os.listdir(os.getcwd())
['hello.py', 'test.txt']

  

  

2,绝对路径shell

  • os.path.abspath(path):返回path的绝对路径。
>>> os.path.abspath( '.' )
'D:\\pythontest\\ostest'
>>> os.path.abspath( '..' )
'D:\\pythontest'

  

3,查看路径的文件夹部分和文件名部分windows

  • os.path.split(path):将路径分解为(文件夹,文件名),返回的是元组类型。能够看出,若路径字符串最后一个字符是\,则只有文件夹部分有值;若路径字符串中均无\,则只有文件名部分有值。若路径字符串有\,且不在最后,则文件夹和文件名均有值。且返回的文件夹的结果不包含\.
  • os.path.join(path1,path2,...):将path进行组合,若其中有绝对路径,则以前的path将被删除。
>>> os.path.split( 'D:\\pythontest\\ostest\\Hello.py' )
( 'D:\\pythontest\\ostest' 'Hello.py' )
>>> os.path.split( '.' )
(' ', ' .')
>>> os.path.split( 'D:\\pythontest\\ostest\\' )
( 'D:\\pythontest\\ostest' , '')
>>> os.path.split( 'D:\\pythontest\\ostest' )
( 'D:\\pythontest' 'ostest' )
>>> os.path.join( 'D:\\pythontest' 'ostest' )
'D:\\pythontest\\ostest'
>>> os.path.join( 'D:\\pythontest\\ostest' 'hello.py' )
'D:\\pythontest\\ostest\\hello.py'
>>> os.path.join( 'D:\\pythontest\\b' 'D:\\pythontest\\a' )
'D:\\pythontest\\a'
  • os.path.dirname(path):返回path中的文件夹部分,结果不包含'\'
>>> os.path.dirname( 'D:\\pythontest\\ostest\\hello.py' )
'D:\\pythontest\\ostest'
>>> os.path.dirname( '.' )
''
>>> os.path.dirname( 'D:\\pythontest\\ostest\\' )
'D:\\pythontest\\ostest'
>>> os.path.dirname( 'D:\\pythontest\\ostest' )
'D:\\pythontest'
  • os.path.basename(path):返回path中的文件名。
>>> os.path.basename( 'D:\\pythontest\\ostest\\hello.py' )
'hello.py'
>>> os.path.basename( '.' )
'.'
>>> os.path.basename( 'D:\\pythontest\\ostest\\' )
''
>>> os.path.basename( 'D:\\pythontest\\ostest' )
'ostest'

  

4,查看文件时间bash

  •  os.path.getmtime(path):文件或文件夹的最后修改时间,重新纪元到访问时的秒数。
  •  os.path.getatime(path):文件或文件夹的最后访问时间,重新纪元到访问时的秒数。
  •  os.path.getctime(path):文件或文件夹的建立时间,重新纪元到访问时的秒数。
>>> os.path.getmtime( 'D:\\pythontest\\ostest\\hello.py' )
1481695651.857048
>>> os.path.getatime( 'D:\\pythontest\\ostest\\hello.py' )
1481687717.8506615
>>> os.path.getctime( 'D:\\pythontest\\ostest\\hello.py' )
1481687717.8506615

  

5,查看文件大小app

  • os.path.getsize(path):文件或文件夹的大小,如果文件夹返回0。
>>> os.path.getsize( 'D:\\pythontest\\ostest\\hello.py' )
58L
>>> os.path.getsize( 'D:\\pythontest\\ostest' )
0L

  

6,查看文件是否存在post

  •  os.path.exists(path):文件或文件夹是否存在,返回True 或 False。
>>> os.listdir(os.getcwd())
[ 'hello.py' 'test.txt' ]
>>> os.path.exists( 'D:\\pythontest\\ostest\\hello.py' )
True
>>> os.path.exists( 'D:\\pythontest\\ostest\\Hello.py' )
True
>>> os.path.exists( 'D:\\pythontest\\ostest\\Hello1.py' )
False

  

7,一些表现形式参数编码

  • os中定义了一组文件、路径在不一样操做系统中的表现形式参数,如:
>>> os.sep
'\\'
>>> os.extsep
'.'
>>> os.pathsep
';'
>>> os.linesep
'\r\n'

  

二,sys模块

sys.argv           命令行参数 List ,第一个元素是程序自己路径
sys.exit(n)        退出程序,正常退出时exit( 0 )
sys.version        获取Python解释程序的版本信息
sys.maxint         最大的 Int
sys.path           返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值
sys.platform       返回操做系统平台名称
sys.stdout.write( 'please:' )   #标准输出 , 引出进度条的例子, 注,在py3上不行,能够用print代替
val  =  sys.stdin.readline()[: - 1 #标准输入
sys.getrecursionlimit()  #获取最大递归层数
sys.setrecursionlimit( 1200 #设置最大递归层数
sys.getdefaultencoding()   #获取解释器默认编码
sys.getfilesystemencoding   #获取内存数据存到文件里的默认编码

1,sys.path :返回模块的搜索路径,初始化使用pythonpath环境变量的值

  sys.path.append("自定义模块路径)url

>>>  import  os
>>>  import  sys
>>> sys.path
[' ', ' D:\\python3\\python36. zip ', ' D:\\python3\\DLLs ', ' D:\\python3\\lib ', ' D:\\python3 ', ' D:\\python3\\lib\\site - packages ', ' D:\\python3\\lib\\site - packages\\win32 ', ' D:\\python3\\lib\\site - packages\\win32\\lib ', ' D:\\python3\\lib\\site - packages\\Pythonwin']
>>>

 

2,进度条:spa

import  sys,time
for  in  range ( 10 ):
     sys.stdout.write( '#' )
     time.sleep( 1 )
     sys.stdout.flush()
 
结果:
##########

  

三,shutil模块

高级的 文件、文件夹、压缩包 处理模块

shutil.copyfileobj(fsrc, fdst[, length])
将文件内容拷贝到另外一个文件中

import  shutil
shutil.copyfileobj( open ( 'old.xml' , 'r' ),  open ( 'new.xml' 'w' ))

  

shutil.copyfile(src, dst)
拷贝文件

shutil.copyfile( 'f1.log' 'f2.log' #目标文件无需存在

  

shutil.copymode(src, dst)
仅拷贝权限。内容、组、用户均不变

shutil.copymode( 'f1.log' 'f2.log' #目标文件必须存在

 

shutil.copystat(src, dst)
仅拷贝状态的信息,包括:mode bits, atime, mtime, flags

shutil.copystat( 'f1.log' 'f2.log' #目标文件必须存在

  

shutil.copy(src, dst)
拷贝文件和权限

import  shutil
shutil.copy( 'f1.log' 'f2.log' )

  

shutil.copy2(src, dst)
拷贝文件和状态信息

import  shutil
shutil.copy2( 'f1.log' 'f2.log' )

  

shutil.ignore_patterns(*patterns)
shutil.copytree(src, dst, symlinks=False, ignore=None)
递归的去拷贝文件夹

import  shutil
shutil.copytree( 'folder1' 'folder2' , ignore = shutil.ignore_patterns( '*.pyc' 'tmp*' ))
#目标目录不能存在,注意对folder2目录父级目录要有可写权限,ignore的意思是排除

  

shutil.rmtree(path[, ignore_errors[, onerror]])
递归的去删除文件

import  shutil
shutil.rmtree( 'folder1' )

  

shutil.move(src, dst)
递归的去移动文件,它相似mv命令,其实就是重命名。

import  shutil
shutil.rmtree( 'folder1' )

  

shutil.make_archive(base_name, format,...)
建立压缩包并返回文件路径,例如:zip、tar
建立压缩包并返回文件路径,例如:zip、tar

  • base_name: 压缩包的文件名,也能够是压缩包的路径。只是文件名时,则保存至当前目录,不然保存至指定路径,

如 data_bak =>保存至当前路径
如:/tmp/data_bak =>保存至/tmp/

  • format: 压缩包种类,“zip”, “tar”, “bztar”,“gztar”
  • root_dir: 要压缩的文件夹路径(默认当前目录)
  • owner: 用户,默认当前用户
  • group: 组,默认当前组
  • logger: 用于记录日志,一般是logging.Logger对象
#将 /data 下的文件打包放置当前程序目录
import  shutil
ret  =  shutil.make_archive( "data_bak" 'gztar' , root_dir = '/data' )
 
#将 /data下的文件打包放置 /tmp/目录
import  shutil
ret  =  shutil.make_archive( "/tmp/data_bak" 'gztar' , root_dir = '/data' )

  

shutil 对压缩包的处理是调用 ZipFile 和 TarFile 两个模块来进行的,详细:
zipfile压缩&解压缩

import  zipfile
 
# 压缩
=  zipfile.ZipFile( 'laxi.zip' 'w' )
z.write( 'a.log' )
z.write( 'data.data' )
z.close()
 
# 解压
=  zipfile.ZipFile( 'laxi.zip' 'r' )
z.extractall(path = '.' )
z.close()

  

tarfile压缩&解压缩

import  tarfile
 
# 压缩
>>> t = tarfile. open ( '/tmp/egon.tar' , 'w' )
>>> t.add( '/test1/a.py' ,arcname = 'a.bak' )
>>> t.add( '/test1/b.py' ,arcname = 'b.bak' )
>>> t.close()
 
# 解压
>>> t = tarfile. open ( '/tmp/egon.tar' , 'r' )
>>> t.extractall( '/egon' )
>>> t.close()

  

四,subprocess模块

  咱们常常须要经过Python去执行一条系统命令或脚本,系统的shell命令是独立于你的python进程以外的,每执行一条命令,就是发起一个新进程,经过python调用系统命令或脚本的模块在python2有os.system,

>> os.system( 'uname -a' )
Darwin Alexs - MacBook - Pro.local  15.6 . 0  Darwin Kernel Version  15.6 . 0 : Sun Jun   4  21 : 43 : 07  PDT  2017 ; root:xnu - 3248.70 . 3 ~ 1 / RELEASE_X86_64 x86_64
0

  

这条命令的实现原理是什么呢?(视频中讲,解释进程间通讯的问题...)

除了os.system能够调用系统命令,,commands,popen2等也能够,比较乱,因而官方推出了subprocess,目地是提供统一的模块来实现对系统命令或脚本的调用

The subprocess module allows you to spawn new processes, connect to their input/output/error pipes, and obtain their return codes. This module intends to replace several older modules and functions:

  • os.system
  • os.spawn*

The recommended approach to invoking subprocesses is to use the run() function for all use cases it can handle. For more advanced use cases, the underlying Popen interface can be used directly.

The run() function was added in Python 3.5; if you need to retain compatibility with older versions, see the Older high-level API section.

三种执行命令的方法

  • subprocess.run(*popenargs, input=None, timeout=None, check=False, **kwargs) #官方推荐

  • subprocess.call(*popenargs, timeout=None, **kwargs) #跟上面实现的内容差很少,另外一种写法

  • subprocess.Popen() #上面各类方法的底层封装

run()方法

Run command with arguments and return a CompletedProcess instance.The returned instance will have attributes args, returncode, stdout and stderr. By default, stdout and stderr are not captured, and those attributes will be None. Pass stdout=PIPE and/or stderr=PIPE in order to capture them.

If check is True and the exit code was non-zero, it raises a CalledProcessError. The CalledProcessError object will have the return code in the returncode attribute, and output & stderr attributes if those streams were captured.

If timeout is given, and the process takes too long, a TimeoutExpired exception will be raised.

The other arguments are the same as for the Popen constructor.

标准写法

subprocess.run([ 'df' , '-h' ],stderr = subprocess.PIPE,stdout = subprocess.PIPE,check = True )

  涉及到管道|的命令须要这样写

 

subprocess.run( 'df -h|grep disk1' ,shell = True #shell=True的
意思是这条命令直接交给系统去执行,不须要python负责解析

  

call()方法

#执行命令,返回命令执行状态 , 0 or 非0
>>> retcode  =  subprocess.call([ "ls" "-l" ])
 
#执行命令,若是命令结果为0,就正常返回,不然抛异常
>>> subprocess.check_call([ "ls" "-l" ])
0
 
#接收字符串格式命令,返回元组形式,第1个元素是执行状态,第2个是命令结果
>>> subprocess.getstatusoutput( 'ls /bin/ls' )
( 0 '/bin/ls' )
 
#接收字符串格式命令,并返回结果
>>> subprocess.getoutput( 'ls /bin/ls' )
'/bin/ls'
 
#执行命令,并返回结果,注意是返回结果,不是打印,下例结果返回给res
>>> res = subprocess.check_output([ 'ls' , '-l' ])
>>> res
b 'total 0\ndrwxr-xr-x 12 alex staff 408 Nov 2 11:05 OldBoyCRM\n'

  

Popen()方法

经常使用参数:

  • args:shell命令,能够是字符串或者序列类型(如:list,元组)
  • stdin, stdout, stderr:分别表示程序的标准输入、输出、错误句柄
  • preexec_fn:只在Unix平台下有效,用于指定一个可执行对象(callable object),它将在子进程运行以前被调用
  • shell:同上
  • cwd:用于设置子进程的当前目录
  • env:用于指定子进程的环境变量。若是env = None,子进程的环境变量将从父进程中继承。

下面这2条语句执行会有什么区别?

a = subprocess.run( 'sleep 10' ,shell = True ,stdout = subprocess.PIPE)
a = subprocess.Popen( 'sleep 10' ,shell = True ,stdout = subprocess.PIPE)

  

区别是Popen会在发起命令后马上返回,而不等命令执行结果。这样的好处是什么呢?

若是你调用的命令或脚本 须要执行10分钟,你的主程序不需卡在这里等10分钟,能够继续往下走,干别的事情,每过一会,经过一个什么方法来检测一下命令是否执行完成就行了。

Popen调用后会返回一个对象,能够经过这个对象拿到命令执行结果或状态等,该对象有如下方法

poll()

Check if child process has terminated. Returns returncode

wait()

Wait for child process to terminate. Returns returncode attribute.

terminate()终止所启动的进程Terminate the process with SIGTERM

kill() 杀死所启动的进程 Kill the process with SIGKILL

communicate()与启动的进程交互,发送数据到stdin,并从stdout接收输出,而后等待任务结束

>>> a  =  subprocess.Popen( 'python3 guess_age.py' ,stdout = subprocess.PIPE,stderr = subprocess.PIPE,stdin = subprocess.PIPE,shell = True )
 
>>> a.communicate(b '22' )
 
(b 'your guess:try bigger\n' , b'')

  

send_signal(signal.xxx)发送系统信号

pid 拿到所启动进程的进程号

 五,configparser模块

此模块用于生成和修改常见配置文档,当前模块的名称在 python 3.x 版本中变动为 configparser。

configparser用于处理特定格式的文件,其本质上是利用open来操做文件。

来看一个好多软件的常见配置文件格式以下

配置文件的格式与windows ini文件相似,能够包含一个或多个节(section),每一个节能够有多个参数(键=值)

[DEFAULT]
ServerAliveInterval  =  45
Compression  =  yes
CompressionLevel  =  9
ForwardX11  =  yes
 
[bitbucket.org]
User  =  hg
 
[topsecret.server.com]
Port  =  50022
ForwardX11  =  no

  

想要生成这样一个文档怎么作?

import  configparser
   
config  =  configparser.ConfigParser()
config[ "DEFAULT" =  { 'ServerAliveInterval' '45' ,
                       'Compression' 'yes' ,
                      'CompressionLevel' '9' }
   
config[ 'bitbucket.org' =  {}
config[ 'bitbucket.org' ][ 'User' =  'hg'
config[ 'topsecret.server.com' =  {}
topsecret  =  config[ 'topsecret.server.com' ]
topsecret[ 'Host Port' =  '50022'      # mutates the parser
topsecret[ 'ForwardX11' =  'no'   # same here
config[ 'DEFAULT' ][ 'ForwardX11' =  'yes'
with  open ( 'example.ini' 'w' ) as configfile:
    config.write(configfile)

  

Config Parser方法

1 、config = ConfigParser.ConfigParser() 
建立ConfigParser实例 
   
2 、config.sections() 
返回配置文件中节序列 
   
3 、config.options(section) 
返回某个项目中的全部键的序列 
   
4 、config.get(section,option) 
返回section节中,option的键值 
   
5 、config.add_section( str
添加一个配置文件节点( str
   
6 、config. set (section,option,val) 
设置section节点中,键名为option的值(val) 
   
7 、config.read(filename) 
读取配置文件 
   
8 、config.write(obj_file) 
写入配置文件 

  

常见异常

异常 描述
ConfigParser.Error 全部异常的基类
ConfigParser.NoSectionError 指定的section没有找到
ConfigParser.DuplicateSectionError 调用add_section() 时,section名称已经被使用
ConfigParser.NoOptionError 指定的参数没有找到
ConfigParser.InterpolationError 当执行字符串插值时出现问题时,出现异常的基类
ConfigParser.InterpolationDepthError 当字符串插值没法完成时,由于迭代次数超过了最大的范围,因此没法完成。InterpolationError的子类
InterpolationMissingOptionError 当引用的选项不存在时,会出现异常。InterpolationError的子类
ConfigParser.InterpolationSyntaxError 当产生替换的源文本不符合所需的语法时,就会出现异常。InterpolationError的子类。
ConfigParser.MissingSectionHeaderError 当试图解析一个没有分段标题的文件时,会出现异常。
ConfigParser.ParsingError 当试图解析文件时发生错误时,会出现异常
ConfigParser.MAX_INTERPOLATION_DEPTH 当raw参数为false时,get()的递归插值的最大深度。这只适用于ConfigParser类

练习:

>>>  import  configparser
>>> config  =  configparser.ConfigParser()
>>> config.sections()
[]
>>> config.read( 'example.ini' )
[ 'example.ini' ]
>>> config.sections()
[ 'bitbucket.org' 'topsecret.server.com' ]
>>>  'bitbucket.org'  in  config
True
>>>  'bytebong.com'  in  config
False
>>> config[ 'bitbucket.org' ][ 'User' ]
'hg'
>>> config[ 'DEFAULT' ][ 'Compression' ]
'yes'
>>> topsecret  =  config[ 'topsecret.server.com' ]
>>> topsecret[ 'ForwardX11' ]
'no'
>>> topsecret[ 'Port' ]
'50022'
>>>  for  key  in  config[ 'bitbucket.org' ]:  print (key)
...
user
compressionlevel
serveraliveinterval
compression
forwardx11
>>> config[ 'bitbucket.org' ][ 'ForwardX11' ]
'yes'

  

其余增删该查语法

  

[group1]
k1  =  v1
k2:v2
 
[group2]
k1  =  v1
 
import  ConfigParser
 
config  =  ConfigParser.ConfigParser()
config.read( 'i.cfg' )
 
# ########## 读 ##########
#secs = config.sections()
#print secs
#options = config.options('group2')
#print options
 
#item_list = config.items('group2')
#print item_list
 
#val = config.get('group1','key')
#val = config.getint('group1','key')
 
# ########## 改写 ##########
#sec = config.remove_section('group1')
#config.write(open('i.cfg', "w"))
 
#sec = config.has_section('wupeiqi')
#sec = config.add_section('wupeiqi')
#config.write(open('i.cfg', "w"))
 
 
#config.set('group2','k1',11111)
#config.write(open('i.cfg', "w"))
 
#config.remove_option('group2','age')
#config.write(open('i.cfg', "w"))
相关文章
相关标签/搜索