zoukankan      html  css  js  c++  java
  • 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__就为绝对模块文件路径,如果你给系统提供相对路径去加载该模块,那么改文件路径为相对路径
  • 相关阅读:
    (转)基于C#的socket编程的TCP异步实现
    socket
    (转)抽象类、抽象属性、抽象方法
    (转)c# 互斥锁
    (转)C#连接OleDBConnection数据库的操作
    c# DLL封装并调用
    网络cmd命令
    (转)UCOSII在任务切换与出入中断时堆栈指针的使用
    app和bootloader跳转 MSP与PSP
    (转)stm32启动文件详解
  • 原文地址:https://www.cnblogs.com/fengliu-/p/9234981.html
Copyright © 2011-2022 走看看