一、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,如下:
sys.path 的作用:
- 与 PYTHONPATH 不同,sys.path 可以在 python 运行后添加我们的 module path,然后直接 import,应该说python只搜索 sys.path 中的 modules,不搜索
- 我们可以通过 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,可以直接添加需要导入的目录为顶层目录,也就是添加到系统变量
二、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时
如下图
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)
比如我们想找一个USER_SETTING,其中并不包含USER_SETTING。
现在我们需要把USER_SETTING添加到系统变量中去。
import os
os.environ['USER_SETTING'] = 'test3'
print(os.environ)