sys.path的使用场景

起因

在初学python时,经常遇到找不到某个路径下的文件,或者在博客中找到的代码需要暴露出环境变量(如linux中可以export PYTHONPATH="$PYTHON;/carla/bin"),发现在windows中配置却没办法识别,这时就可以用到sys.path

使用场景

  • 解决import不到文件的问题 ModuleNotFoundError: No module named 'xxxx'
    目录结构
    D:.
    └─t1
    │  └─t11
    │     └─t11_c.py
    └─ test.py
    
    t11_c.py文件内容
    def example():
        print("t11")
    
    在test.py中希望直接引用t11_c.py
    from t11_c import example
    example()
    
    运行后异常:
    Traceback (most recent call last):
      File "D:/python_projects/pythonProject/test_egg/test.py", line 3, in <module>
        from t11_c import example
    ModuleNotFoundError: No module named 't11_c'
    
    如果将路径加入到系统变量中:
    import sys
    sys.path.append("t1/t11")
    from t11_c import example
    example()
    sys.path.pop(-1)
    
    执行结果:
    t11
    
    我们既可以在路径中写文件夹的相对位置,也可以写绝对位置,这为我们跨项目调用包提供了思路
    import sys
    sys.path.append(r"D:\python_projects\pythonProject\test_egg\t1\t11")
    from t11_c import example
    example()
    print(sys.path.pop(-1))
    
    sys.path.pop(-1) 在退出时清理掉插入的路径,养成良好的习惯
    结论:
    sys.path本质上是一个list,python项目在找引用文件时会在sys.path中挨个寻找
  • 解决包名称相同时,import到自己想要的文件的情况
    这个场景用在将自己写的包放在其他项目时,其他项目中也有和自己项目中引入路径相同的文件,导致引用错误
    目录结构
    D:.
    ├─t2
    │  ├─t21
    │  │  └─main.py
    │  │  └─utils.py
    │  └─__init__.py
    └─test.py
    └─utils.py
    
    t2/t21/main.py
    from utils import example
    def main():
        example()
    
    t2/t21/utils.py
    def example():
        print("t22")
    
    test.py (这里写的是直接拿路径去找,也可以使用python代码从命令行调用)
    from t2.t21.main import main
    if __name__ == '__main__':
        main()
    
    utils.py
    def t2_test():
        print("main")
    
    执行test.py:
    Traceback (most recent call last):
      File "D:/python_projects/pythonProject/test_egg/test.py", line 1, in <module>
        from t2.t21.main import main
      File "D:\python_projects\pythonProject\test_egg\t2\t21\main.py", line 1, in <module>
        from utils import example
    ImportError: cannot import name 'example' from 'utils' (D:\python_projects\pythonProject\test_egg\utils.py)
    
    这里main.py是从根目录下的utils.py中去找example函数,当然找不到。我们可以试着改造main.py,让它在当前目录去找
    main.py
    import sys
    import os
    current_dir_path = os.path.split(os.path.realpath(__file__))[0]  # D:\python_projects\pythonProject\test_egg\t2\t21
    sys.path.insert(0, current_dir_path)
    from utils import example
    def main():
        example()
    print(sys.path.pop(0))
    
    结果:
    D:\python_projects\pythonProject\test_egg\t2\t21
    t22
    
  • 动态调用想使用的文件
    这个和上面的原理很相似,目录结构
    D:.
    ├─t3
    │  ├─t31
    │  │  └─main.py
    │  └─t32
    │      └─main.py
    └─test.py
    
    t31/main.py和t32/main.py内容相似只是t31中打印"t31", t32中打印"t32",都是p函数
    def p():
        print("t31")
    
    test.py:
    import sys
    
    if __name__ == '__main__':
        arg = "t32"
        if arg == "t31":
            path = "t3/t31"
        else:
            path = "t3/t32"
        sys.path.append(path)
        from main import test
        test()
        sys.path.pop(-1)
    
    arg = "t32" 可以理解为通过参数解析或者函数传参调用
    结果:
    t32
    
  • 加载egg文件
    这里的egg包是在carla打包时生成的egg包carla-0.9.13-py3.8-win-amd64.egg
    可以这么引入egg包
    test.py:
    import sys
    sys.path.append("carla-0.9.13-py3.8-win-amd64.egg")
    
    import carla
    
    if __name__ == '__main__':
        print(carla)
    
    结果
    <module 'carla' from 'carla-0.9.13-py3.8-win-amd64.egg\\carla\\__init__.py'>
    
posted @ 2022-09-05 15:11  luslin  阅读(199)  评论(0)    收藏  举报