一、sys.path

我们首先了解下PATH、PYTHONPATH 和 sys.path 的区别

PATH

在PATH中的 python module 不能被 import,在 PATH 中的一些命令,例如 *.exe,可以直接在cmd中运行,而不用明确的路径,我们在给 python 安装一些 packages 的时候,有一些 Scripts 被安装到 /Scripts 文件夹中,如果 /Scripts 文件夹路径不在 PATH 中,会有提示

PYTHONPATH

如果我们使用 PYTHONPATH 中的 modules,那么在运行 python 前,就要把 path 加到 os.environ['PYTHONPATH'],在运行 python 后再加,那些模块不能直接被导入

sys.path

官方文档说明:A list of strings that specifies the search path for modules. Initialized from the environment variable PYTHONPATH, plus an installation-dependent default.

sys.path 初始化的时候有两部分:os.environ['PYTHONPATH'] 和 默认的安装依赖的一些路径(例如 python 安装的根目录 和 pythonxx.zip),是python的搜索模块的路径集,是一个list,如下:

python sys path append 恢复 sys.path python_python

sys.path 的作用:

  1. 与 PYTHONPATH 不同,sys.path 可以在 python 运行后添加我们的 module path,然后直接 import,应该说python只搜索 sys.path 中的 modules,不搜索 
  2. 我们可以通过 os.environ['PYTHONPATH'] 来传递我们的 module path(下文会介绍)

     3.在实际开发中,默认包含了当前目录为搜索路径,所以,当前目录下的模块和子模块均可以正常访问。但是若一个模块需要import平级的不同目录的模块,或者上级目录里面的模块,就可以通过修改path来实现
这是即时生效的方法,就是在模块里面修改sys.path值,这种方法修改的sys.path作用域只是当前进程,进程结束后就失效了。
个人比较推荐这种方法,比较干净, 避免一些冲突问题。
比如现在的代码目录结构:

/src/configs/config.py
/src/common/Database.py

假如Database.py期望导入config. py,则可以增加上级目录到sys.path列表里面:

parent_path = os.path.dirname(sys.path[0])
if parent_path not in sys.path:
    sys.path.append(parent_path)
import configs.config

    4. 如果是在使用pycharm IDE,可以直接添加需要导入的目录为顶层目录,也就是添加到系统变量

python sys path append 恢复 sys.path python_linux_02

 

二、os.path

abspath: 返回一个文件的绝对路径

import os
os.path.abspath("/etc/sysconfig/selinux")
# '/etc/sysconfig/selinux'
os.getcwd()
# '/root'
os.path.abspath("python_modu")
# '/root/python_modu'
os.path.abspath(__file__)  # 返回当前文件的绝对路径
# /opt/project/test3.py

basename: 返回一个目录的基名

os.path.basename("/etc/sysconfig/selinux")
# 'selinux'
os.path.basename("/usr/local/python3/bin/python3")
# 'python3'

dirname:返回一个目录的目录名

os.path.dirname("/etc/sysconfig/selinux")
# '/etc/sysconfig'
os.path.dirname("/usr/local/python3/bin/python3")
# '/usr/local/python3/bin'

还有其他参数可参考:、Python os.path() 模块

说一下日常使用:

os.path.dirname(__file__)返回脚本的路径

1、必须是实际存在的.py文件,如果在命令行执行,则会引发异常NameError: name '__file__' is not defined

2、在运行的时候如果输入完整的执行的路径,则返回.py文件的全路径如:

python c:/test/test.py 则返回路径 c:/test ,如果是python test.py 则返回空

3、结合os.path.abspath用,效果会好,如果大家看过一些python架构的代码的话,会发现经常有这样的组合

os.path.dirname(os.path.abspath(__file__)),os.path.abspath(__file__)返回的是.py文件的绝对路径

这就是os.path.dirname(__file__)的用法,其主要总结起来有:
1、不要已命令行的形式来进行os.path.dirname(__file__)这种形式来使用这个函数

2、结合os.path.abspath()使用

可以os.path.abspath()和os.path.dirname()结合使用达到获取其他路径的文件名

一个典型的例子就是Python Django获取.env时

如下图

python sys path append 恢复 sys.path python_linux_03

DIRNAME = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))

# 读取数据库配置文件
config_file = os.path.join(DIRNAME, '.env')

os.environ

官方文档的意思,根据一个字符串可以映射到一个对象,比如,environ['HOME']是这个平台的主目录,作用相当于getenv("HOME")

首次导入os模块时(通常是在Python启动期间作为处理site.py的一部分)捕获了此映射。 此时间之后对环境所做的更改不会反映在os.environ中,除非直接修改os.environ进行更改。

简单的说就是可以根据一个字符串映射到系统环境的一个对象,在首次导入os模块的时候已经捕获了系统的映射,可以通过os.environ进行更改。

import os

print(os.environ)

python sys path append 恢复 sys.path python_python_04

比如我们想找一个USER_SETTING,其中并不包含USER_SETTING。

现在我们需要把USER_SETTING添加到系统变量中去。

import os
os.environ['USER_SETTING'] = 'test3'
print(os.environ)

python sys path append 恢复 sys.path python_linux_05