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

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

  1. Python模块详解以及import本质,获得文件当前路径os.path.abspath,获得文件的父目录os.path.dirname,放到系统变量的第一位sys.path.insert(0,x)

    模块介绍 1.定义: 模块:用来从逻辑上组织python代码(变量,函数,类,逻辑:实现一个功能),本质就是.py结尾的python文件(文件名:test.py,对应的模块名:test) 包:用来从逻 ...

  2. python sys.path[0] 的解释

    sys.path是python的搜索模块的路径集,返回的结果是一个list path[0] 此列表的第一项,path[0],在程序启动时初始化,是包含用来调用Python解释器的脚本的目录.如果脚本目 ...

  3. sys.path.insert(0,"/path") 的用法

    可以选择用sys.path.insert(0,‘/path’),这样新添加的目录会优先于其他目录被import检查

  4. [项目实践] python文件路径引用的规则,记一次使用sys.path[0]的问题,及如何区分 ../与 ./的使用场景

    下面是一个获取配置的代码 def getValue(self,section,option): """ @file: string,the name of the con ...

  5. python基础-7模块,第三方模块安装方法,使用方法。sys.path os sys time datetime hashlib pickle json requests xml

    模块,用一砣代码实现了某个功能的代码集合. 类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合.而对于一个复杂的功能来,可能需要多个函数才 ...

  6. python中os.path 与sys.path

    看别人写的代码,会发现两个和路径设置有关的模块 os 和sys.我对这两个模块也不是特别了解.只是记录一下自己看到的,学到的. python 中我们会使用这两个模块和文件路径, 创建文件 之类的 操作 ...

  7. [python] os.path.join() 与 sys.path

    脚本文件本地目录挂入系统环境变量 import sys, os sys.path.append(os.pardir) print(sys.path) os.getcwd()获取当前目录路径 impor ...

  8. fio 测试 磁盘I/O: ls -1 /sys/block/sda/queue/ | awk '{cmd="cat "i$0; print i$0; system(cmd) }' i=`pwd`'/'

    小型计算机系统接口(SCSI,Small Computer System Interface) SAS(Serial Attached SCSI,串列SCSI) SCSI 硬盘名称: sd[a-p] ...

  9. 【原创】os.chdir设置的工作路径和sys.path之间到底是个啥关系?

    转载请注明出处:https://www.cnblogs.com/oceanicstar/p/9390455.html   直接放上测试后的结论(测试代码和截图过多,有兴趣的小伙伴可自己测试,未来看情况 ...

随机推荐

  1. 用JavaScript写一个区块链

    几乎每个人都听说过像比特币和以太币这样的加密货币,但是只有极少数人懂得隐藏在它们背后的技术.在这篇博客中,我将会用JavaScript来创建一个简单的区块链来演示它们的内部究竟是如何工作的.我将会称之 ...

  2. fitnesse - 框架介绍

    fitnesse - 框架介绍 2017-09-29 目录: 1 fitnesse是什么?2 框架介绍3 与junit.testng比较,fitnesse教其他框架有什么优势 1 fitnesse是什 ...

  3. webpack4: compilation.mainTemplate.applyPluginsWaterfall is not a function 解决方法

    今天捣鼓webpack4踩到一个弥天大坑:使用html-webpack-plugin打包html的时候一直报 compilation.mainTemplate.applyPluginsWaterfal ...

  4. Eslint报错整理与解决方法(持续整理)

    1.'Unexpected tab character' 字面意思理解呢就是意想不到的制表符,当时出现的时候就是我习惯的使用Tab键去打空格,但是eslint默认不认可Tab,所以解决方法很简单: 在 ...

  5. java单点登录原理与简单实现

    一.单系统登录机制 1.http无状态协议 web应用采用browser/server架构,http作为通信协议.http是无状态协议,浏览器的每一次请求,服务器会独立处理,不与之前或之后的请求产生关 ...

  6. PHP的日志记录-错误与异常记录

    PHP的日志记录-错误与异常记录 提到 Nginx + PHP 服务的错误日志,我们通常能想到的有 Nginx 的 access 日志.error 日志以及 PHP 的 error 日志.虽然看起来是 ...

  7. python函数式编程之yield表达式形式

    先来看一个例子 def foo(): print("starting...") while True: res = yield print("res:",res ...

  8. Java设计模式-合成模式

    合成模式有时也叫组合模式,对象组合成树形结构以表示"部分-整体"的层次结构,组合模式使得用户对单个对象和组合对象的使用具有一致性.掌握组合模式的重点是要理解清楚 "部分/ ...

  9. Java面向对象特性--多态

    Java是一种面向对象的编程语言,面向对象的三大特性就是继承,封装,多态.下面细细说一说多态. 多态的定义:一个事物的多种形态,指允许不同类的对象对同一消息做出响应.即同一消息可以根据发送对象的不同而 ...

  10. 掌握这些知识,你的python水平能更上一层楼(续)

    笔者的上一篇python文章阅读量不错,看来python爱好者很多,所以再写一篇,以飨读者. 先接着上一篇讲一个问题,下面这段code有没有问题? def countcalls(func): coun ...