<span id="7ztzv"></span>
<sub id="7ztzv"></sub>

<span id="7ztzv"></span><form id="7ztzv"></form>

<span id="7ztzv"></span>

        <address id="7ztzv"></address>

            16.2. 找到路徑

            從命令行運行 Python 代碼時,知道所運行代碼在磁盤上的存儲位置有時候是有必要的。

            這是一個不那么容易想起,但一想起就很容易解決的小麻煩。答案是 sys.argv。正如你在 第 9 章 XML 處理 中看到的,它包含了很多命令行參數。它也同樣記錄了運行腳本的名字,和你調用它時使用的命令一摸一樣。這些信息足以令我們確定文件的位置。

            例 16.3. fullpath.py

            如果您還沒有下載本書附帶的樣例程序, 可以 下載本程序和其他樣例程序

            
            import sys, os
            
            print 'sys.argv[0] =', sys.argv[0]             1
            pathname = os.path.dirname(sys.argv[0])        2
            print 'path =', pathname
            print 'full path =', os.path.abspath(pathname) 3
            1 無論如何運行一段腳本,sys.argv[0] 總是包含腳本的名字,和調用時使用的命令一摸一樣。你很快會發現,它不一定包含任何路徑信息。
            2 os.path.dirname 接受作為字符串傳來的文件名并返回路徑部分。如果給定的文件名不包含任何路徑信息,os.path.dirname 返回空字符串。
            3 os.path.abspath 是這里的關鍵。它接受的路徑名可以是部分的甚至是完全空白,但總能返回完整有效的路徑名。

            進一步地解釋 os.path.abspath 是有必要的。它非常靈活,可以接受任何類型的路徑名。

            例 16.4. os.path.abspath 的進一步解釋

            >>> import os
            >>> os.getcwd()                        1
            /home/you
            >>> os.path.abspath('')                2
            /home/you
            >>> os.path.abspath('.ssh')            3
            /home/you/.ssh
            >>> os.path.abspath('/home/you/.ssh') 4
            /home/you/.ssh
            >>> os.path.abspath('.ssh/../foo/')    5
            /home/you/foo
            1 os.getcwd() 返回當前的工作路徑。
            2 用空字符串調用 os.path.abspath 將返回當前的工作路徑,與 os.getcwd()的效果相同。
            3 以不完整的路徑名調用 os.path.abspath 可以構建一個基于當前工作路徑且完整有效的路徑名。
            4 以完整的路徑名調用 os.path.abspath 則簡單地將其直接返回。
            5 os.path.abspath格式化 返回的路徑名。注意這個例子在我根本沒有‘foo’目錄時同樣奏效。os.path.abspath 從不檢查你的磁盤,而僅僅是字符串操作。
            注意
            傳遞給 os.path.abspath 的路徑名和文件名可以不存在。
            注意
            os.path.abspath 不僅構建完整路徑名,還能格式化路徑名。這意味著如果你正工作于 /usr/ 目錄,os.path.abspath('bin/../local/bin') 將會返回 /usr/local/bin。它把路徑名格式化為盡可能簡單的形式。如果你只是希望簡單地返回這樣的格式化路徑名而不需要完整路徑名,可以使用 os.path.normpath

            例 16.5. fullpath.py 的樣例輸出

            [you@localhost py]$ python /home/you/diveintopython/common/py/fullpath.py 1
            sys.argv[0] = /home/you/diveintopython/common/py/fullpath.py
            path = /home/you/diveintopython/common/py
            full path = /home/you/diveintopython/common/py
            [you@localhost diveintopython]$ python common/py/fullpath.py               2
            sys.argv[0] = common/py/fullpath.py
            path = common/py
            full path = /home/you/diveintopython/common/py
            [you@localhost diveintopython]$ cd common/py
            [you@localhost py]$ python fullpath.py                                     3
            sys.argv[0] = fullpath.py
            path = 
            full path = /home/you/diveintopython/common/py
            1 在第一種情況下,sys.argv[0] 包含代碼的完整路徑。你可以通過 os.path.dirname 函數將文件名從其中剝離出來并返回完整的路徑,os.path.abspath 則是簡單地把你傳遞給它的值返回。
            2 如果腳本是以不完整路名被運行的,sys.argv[0] 還是會包含命令行中出現的一切。os.path.dirname 將會給你一個 (相對于當前工作路徑的) 不完整的路徑名,os.path.abspath 將會以不完整路徑名為基礎構建一個完整的路徑名。
            3 如果沒有給定任何路徑,而是從當前目錄運行腳本,os.path.dirname 將簡單地返回一個空字符串。由于是從當前目錄運行腳本,os.path.abspath 將針對給定的空字符串給出你所希望獲知的當前目錄。
            注意
            就像 osos.path 模塊的其他函數,os.path.abspath 是跨平臺的。如果你是在 Windows (使用反斜杠作為路徑符號) 或 Mac OS (使用冒號) 上運行,它們同樣工作,只是將獲得與我稍有不同的結果。os 的所有函數都是這樣的。

            補充. 一位讀者對這個結果并不滿意,他希望能夠從當前路徑運行所有單元測試,而不是從 regression.py 所在目錄運行。他建議以下面的代碼加以取代:

            例 16.6. 在當前目錄運行腳本

            import sys, os, re, unittest
            
            def regressionTest():
                path = os.getcwd()       1
                sys.path.append(path)    2
                files = os.listdir(path) 3
            
            1 不是將 path 設置為運行代碼所在的路徑,而是將它設置為當前目錄。可以是你在運行腳本之前所在的任何路徑,而不需要是運行腳本所在的路徑。(多次體味這句話,直到你真正理解了它。)
            2 將這個目錄添加到 Python 庫搜索路徑中,你稍后動態導入單元測試模塊時,Python 就能找到它們了。如果 path 就是正在運行代碼的存儲目錄,你就不需要這樣做了,因為 Python 總會查找這個目錄。
            3 函數的其他部分不變。

            這個技術允許你在多個項目中重用 regression.py 代碼。只需要將這個代碼放在一個普通目錄中,在運行項目前將路徑更改為項目的目錄。項目中所有的單元測試被找到并運行,而不僅僅局限于 regression.py 所在目錄的單元測試。

            <span id="7ztzv"></span>
            <sub id="7ztzv"></sub>

            <span id="7ztzv"></span><form id="7ztzv"></form>

            <span id="7ztzv"></span>

                  <address id="7ztzv"></address>

                      亚洲欧美在线