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"))
相關文章
相關標籤/搜索