os.getcwd()、sys.path[0]、sys.argv[0]和__file__的區別,終於弄清楚了


os.getcwd()、sys.path[0]、sys.argv[0]和__file__的區別

要分清這幾個的區別與使用條件,實際測試一下是最准確的。

設計測試方法:

一個主模塊用來運行,一個子模塊用來被主模塊調用

主模塊路徑: 

/Users/stephen/Documents/code/test_dir/01test

子模塊路徑:  

/Users/stephen/Documents/code/test_dir/02test

運行模塊的路徑:  

/Users/stephen/Documents/code/test_dir/01test/001_test

ok 現在編寫兩模塊代碼

  • 子模塊 submodule.py
import os
import sys
def child_test():
    print('sub os.getcwd():{}'.format(os.getcwd()))
    print('sub sys.path[0]:{}'.format(sys.path[0]))
    print('sub sys.argv[0]:{}'.format(sys.argv[0]))
    print('sub __file__:{}'.format(__file__))
if __name__ == '__main__':
    chid_test()
  • 主模塊 mainmodule.py
import os
import sys
import submodule
def main():
    print('main os.getcwd():{}'.format(os.getcwd()))
    print('main sys.path[0]:{}'.format(sys.path[0]))
    print('main sys.argv[0]:{}'.format(sys.argv[0]))
    print('main __file__:{}'.format(__file__))

    submodule.child_test()
if __name__ == '__main__':
    main()

目錄結構

├── 01test
│   ├── 001_test      # 運行目錄
│   └── mainmodule.py # 主模塊
└── 02test 
    └── submodule.py  # 被調用模塊

ok 來看看結果

Traceback (most recent call last):
  File "../mainmodule.py", line 3, in <module>
    import submodule
ModuleNotFoundError: No module named 'submodule'

我去,出現了點小狀況

原因是系統找不到該模塊的路徑,我們來人工添加一個路徑
在主模塊中前面添加

sys.path.append('/Users/stephen/Documents/code/test_dir/02test/')

再來試試 - -

結果如下:

main os.getcwd():/Users/stephen/Documents/code/test_dir/01test/001_test
main sys.path[0]:/Users/stephen/Documents/code/test_dir/01test
main sys.argv[0]:../mainmodule.py
main __file__:../mainmodule.py
sub os.getcwd():/Users/stephen/Documents/code/test_dir/01test/001_test
sub sys.path[0]:/Users/stephen/Documents/code/test_dir/01test
sub sys.argv[0]:../mainmodule.py
sub __file__:/Users/stephen/Documents/code/test_dir/02test/submodule.py

結合目錄結構看就清楚了

├── 01test
│   ├── 001_test      # 運行目錄
│   └── mainmodule.py # 主模塊
└── 02test 
    └── submodule.py  # 被調用模塊

  • os.getcwd() 指的是運行程序的目錄 (絕對路徑)
  • sys.path[0] 主要模塊的目錄 (絕對路徑)
  • sys.argv[0] 運行模塊時,pyhton 后面的參數
  • __file__ 這個就有點奇怪了,主模塊顯示的相對路徑,而被調用模塊卻用的絕對路徑

__file__ 還是有點疑慮,於是去 stack overflow(click to)看到了這句話,如下:

So, if you are outside the part of sys.path that contains the module, you'll get an absolute path. If you are inside the part of sys.path that contains the module, you'll get a relative path.

If you load a module in the current directory, and the current directory isn't in sys.path, you'll get an absolute path.

If you load a module in the current directory, and the current directory is in sys.path, you'll get a relative path.

意思大致是:

如果你(你所在的當前目錄)不在sys.path的范圍里,你會得到絕對路徑,反之,你會得到相對路徑

如果你在當前目錄加載模塊,並且當前目錄在sys.path 里, 你會得到相對路徑。

對比上面的結果,符合。

不過我們還是應該再來驗證下。我們把當前路徑換到子模塊下

├── 01test
│   ├── 001_test     
│   └── mainmodule.py # 主模塊
└── 02test            # 當前目錄
    └── submodule.py  # 被調用模塊

結果如下:

main os.getcwd():/Users/stephen/Documents/code/test_dir/02test
main sys.path[0]:/Users/stephen/Documents/code/test_dir/01test
main sys.argv[0]:../01test/mainmodule.py
main __file__:../01test/mainmodule.py
sub os.getcwd():/Users/stephen/Documents/code/test_dir/02test
sub sys.path[0]:/Users/stephen/Documents/code/test_dir/01test
sub sys.argv[0]:../01test/mainmodule.py
sub __file__:/Users/stephen/Documents/code/test_dir/02test/submodule.py

是不是覺得有問題?幸虧我們測試了

突然想起我我運行mainmodule用的相對路徑
像這樣:

$ python ../01test/mainmodule.py

然后__file__就是相對路徑的,如果我們換成絕對路徑呢?

$ python /Users/stephen/Documents/code/test_dir/01test/mainmodule.py

結果如下:

main os.getcwd():/Users/stephen/Documents/code/test_dir/02test
main sys.path[0]:/Users/stephen/Documents/code/test_dir/01test
main sys.argv[0]:/Users/stephen/Documents/code/test_dir/01test/mainmodule.py
main __file__:/Users/stephen/Documents/code/test_dir/01test/mainmodule.py
sub os.getcwd():/Users/stephen/Documents/code/test_dir/02test
sub sys.path[0]:/Users/stephen/Documents/code/test_dir/01test
sub sys.argv[0]:/Users/stephen/Documents/code/test_dir/01test/mainmodule.py
sub __file__:/Users/stephen/Documents/code/test_dir/02test/submodule.py

soga!
終於弄清楚了,突然有種小興奮啊
總結一下:

  • os.getcwd() 指的是當前目錄,絕對路徑
  • sys.path[0] sys.path 指的是path,sys.path[0]為主模塊目錄的絕對路徑,在模塊運行的時候被自動添加進去
  • sys.argv[0] 就是你運行時 python 后面跟的參數
  • __file__ 表示所在模塊文件的路徑,和系統找到該模塊的方式有關,你是用絕對路徑去加載該模塊,那么__file__就為絕對模塊文件路徑,如果你給系統提供相對路徑去加載該模塊,那么改文件路徑為相對路徑


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM