os.getcwd()、sys.path[0]、sys.argv[0]和__file__的区别,终于弄清楚了

本文通过实验对比os.getcwd()、sys.path[0]、sys.argv[0]和__file__在不同情况下的表现,揭示它们在Python程序中的作用及差异。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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__就为绝对模块文件路径,如果你给系统提供相对路径去加载该模块,那么改文件路径为相对路径

转载于:https://www.cnblogs.com/fengliu-/p/9234981.html

import os import time from PySide2.QtWidgets import QApplication, QProgressBar, QTextBrowser, \ QFileDialog from PySide2.QtUiTools import QUiLoader from PySide2 import QtCore from auto_accounting import AutoAccounting class MainWindows: def __init__(self): self.ui = QUiLoader().load('./ui/auto_accounting.ui') self.ele_dir_path = "" self.fuel_dir_path = "" self.ui.import_electric.clicked.connect(self.import_electric_path) self.ui.import_fuel.clicked.connect(self.import_fuel_path) self.ui.start.clicked.connect(self.go_statics) @staticmethod def __tb_display(tb, word: str = '', middle: bool = True, clear: bool = True): if clear: tb.clear() if word: tb.append(word) if middle: tb.setAlignment(QtCore.Qt.AlignCenter) def import_electric_path(self): self.ele_dir_path = QFileDialog.getExistingDirectory(None, "选择充电发票路径", os.getcwd()) self.ele_dir_path = f"{self.ele_dir_path}/" self.__tb_display(tb=self.ui.electric_file_path_display, word=self.ele_dir_path, middle=False) def import_fuel_path(self): self.fuel_dir_path = QFileDialog.getExistingDirectory(None, "选择加油发票路径", os.getcwd()) self.fuel_dir_path = f"{self.fuel_dir_path}/" self.__tb_display(tb=self.ui.fuel_file_path_display, word=self.fuel_dir_path, middle=False) def go_statics(self): self.__tb_display(tb=self.ui.monitor, word="统计中...", middle=False) if not self.ele_dir_path and not self.fuel_dir_path: self.__tb_display(tb=self.ui.monitor, word="请至少添加一个路径!", middle=False) return False A = AutoAccounting(electric_path=self.ele_dir_path, fuel_path=self.fuel_dir_path) files_ck_res = A.bill_abstract() if files_ck_res: self.__tb_display(tb=self.ui.monitor, word="", middle=False) for file_ck_res in files_ck_res: words = file_ck_res[1]+file_ck_res[2] self.__tb_display(tb=self.ui.monitor, word=words, middle=False, clear=False) elif A.wrong_bills: print(A.wrong_bills) self.__tb_display(tb=self.ui.monitor, word="", middle=False) for wrong_bill in A.wrong_bills: self.__tb_display(tb=self.ui.monitor, word=wrong_bill, middle=False, clear=False) else: self.__tb_display(tb=self.ui.monitor, word="已完成发票统计!", middle=False) app = QApplication([]) stats = MainWindows() stats.ui.show() app.exec_() 为什么”统计中...“无法显示在monitor文本框内
最新发布
07-23
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值