問題描述
最近利用python
構(gòu)建工作腳本的時候,需要把混用之前的shell
腳本曹动。但是在互相調(diào)用的時候谚中,發(fā)現(xiàn)原本運行完好的python
腳本出現(xiàn)了尋找文件上的問題。
在python
腳本中林艘,利用了ConfigParser
模塊來使用config
文件盖奈。
# ...
config = ConfigParser.ConfigParser()
config.read("config.ini")
# ...
config.ini
文件和這個python
腳本處于同一目錄中,因此單獨運行此腳本的時候狐援,沒有任何問題钢坦。
之后究孕,由于需要在一個shell
腳本中使用這個腳本,而shell
腳本在另一個目錄中爹凹,這個時候就出現(xiàn)了找不到文件的問題厨诸,表現(xiàn)為config
解析錯誤。因此禾酱,這里我使用了腳本文件的路徑來試圖補全config
文件的路徑微酬。
# ...
config = ConfigParser.ConfigParser()
config.read(os.path.dirname(sys.argv[0]) + "config.ini")
# ...
暫時這個文件表現(xiàn)良好。但是隨后這個python
文件需要調(diào)用同一文件夾下的另一個模塊宇植,這個模塊中也使用了config
文件得封,因此如法炮制,我又使用了上面的方法來加載config.ini
指郁,結(jié)果發(fā)生了之前同樣的錯誤忙上。經(jīng)過在網(wǎng)上研究,最終改成如下形式:
# ...
config = ConfigParser.ConfigParser()
config.read(os.path.dirname(os.path.realpath(__file__)) + "config.ini")
# ...
這樣最終達(dá)成了需求闲坎。
原理分析
最開始使用的方法是使用系統(tǒng)搜索路徑直接尋找這個文件疫粥,在該目錄中使用的時候沒問題,因為python
會將sys.argv[0]
自行加入sys.path
中腰懂。因此可以尋找到本目錄的文件梗逮。但是換一個目錄就找不到這個文件了,因此報錯绣溜。
第二次使用sys.argv[0]
尋找文件慷彤。在被其他模塊使用的時候,sys.argv[0]
會變成只有文件名沒有路徑的形式怖喻,因此找不到文件底哗。
第三次使用__file__
,這個是直指本文件路徑的锚沸,因此可以使用跋选。
相關(guān)擴展
os模塊的使用
os.sep 可以取代操作系統(tǒng)特定的路徑分割符。
os.name字符串指示你正在使用的平臺哗蜈。比如對于Windows前标,它是'nt',而對于Linux/Unix用戶距潘,它是'posix'炼列。
os.getcwd()函數(shù)得到當(dāng)前工作目錄,即當(dāng)前Python腳本工作的目錄路徑音比。
os.getenv()和os.putenv()函數(shù)分別用來讀取和設(shè)置環(huán)境變量唯鸭。
os.listdir()返回指定目錄下的所有文件和目錄名。
os.remove()函數(shù)用來刪除一個文件硅确。
os.system()函數(shù)用來運行shell命令目溉。
os.linesep字符串給出當(dāng)前平臺使用的行終止符。例如菱农,Windows使用'\r\n'缭付,Linux使用'\n'而Mac使用'\r'。
os.path.split()函數(shù)返回一個路徑的目錄名和文件名循未。
os.path.isfile()和os.path.isdir()函數(shù)分別檢驗給出的路徑是一個文件還是目錄陷猫。
os.path.existe()函數(shù)用來檢驗給出的路徑是否真地存在
os和os.path模塊
os.listdir(dirname):列出dirname下的目錄和文件
os.getcwd():獲得當(dāng)前工作目錄
os.curdir:返回但前目錄('.')
os.chdir(dirname):改變工作目錄到dirname
os.path.isdir(name):判斷name是不是一個目錄,name不是目錄就返回false
os.path.isfile(name):判斷name是不是一個文件的妖,不存在name也返回false
os.path.exists(name):判斷是否存在文件或目錄name
os.path.getsize(name):獲得文件大小绣檬,如果name是目錄返回0L
os.path.abspath(name):獲得絕對路徑
os.path.normpath(path):規(guī)范path字符串形式
os.path.split(name):分割文件名與目錄(事實上,如果你完全使用目錄嫂粟,它也會將最后一個目錄作為文件名而分離娇未,同時它不會判斷文件或目錄是否存在)
os.path.splitext():分離文件名與擴展名
os.path.join(path,name):連接目錄與文件名或目錄
os.path.basename(path):返回文件名
os.path.dirname(path):返回文件路徑
os.path.realpath():返回文件的路徑
sys模塊的使用
sys.argv
一個包含了腳本名稱和傳入?yún)?shù)的list
。
sys.path
搜索路徑的list星虹,可以通過插入路徑的方式添加搜索路徑零抬。
sys.builtin_module_names
所有的內(nèi)建模塊。
sys.modules
所有已經(jīng)導(dǎo)入的模塊宽涌。
sys.platform
系統(tǒng)平臺平夜。
sys.stdout
標(biāo)準(zhǔn)輸出。
sys.stderr
標(biāo)準(zhǔn)錯誤輸出卸亮。
sys.exit
退出程序忽妒。
sys.exitfunc
退出程序的時候調(diào)用的函數(shù),可以自己替換兼贸。
常用python模塊的私有變量
__file__
該腳本的路徑
__name__
該腳本的名稱段直。直接調(diào)用這個腳本的時候會被給一個省缺值__main__
∏奘埽可以借此判斷執(zhí)行方式和編寫單元測試坷牛。
__doc__
這個對象的描述。在模塊起始或者類起始用形如
"""
description
"""
這樣的方式寫出的描述文字很澄。
三種獲取路徑方式的區(qū)別
在之前的介紹中京闰,涉及到了三種獲取路徑的方式。分別是os.getcwd()
甩苛,__file__
和sys.argv[0]
蹂楣。這三種方式在直接使用腳本的時候返回是基本一致的。但是也有區(qū)別讯蒲。
os.getcwd()
獲得的是當(dāng)前工作目錄的路徑痊土。與腳本所在路徑可能不一致。
__file__
則是腳本的文件名墨林,有時是絕對路徑赁酝,有時是相對路徑犯祠,但是都指向了使用該變量的腳本。
sys.argv[0]
是調(diào)用腳本的時候使用的文件名酌呆。其實相當(dāng)于調(diào)用python
命令的時候的第一個參數(shù)衡载。因此,有時候可能沒有路徑只有文件名隙袁。
在使用文件名之前一定要分辨清楚痰娱,否則可能會有這次一樣,時有時無的報錯菩收。