python工作目录与文件目录
工作目录
文件目录:文件所在的目录
工作目录:执行python命令所在的目录
D:.
| main.py
|
+---data
| data.txt
|
+---model
| | model.py
| | train.py
| | __init__.py
| |
| +---nlp
| | | bert.py
|
\---util| view.py| __init__.py
我们以上图为例,很容易知道main.py
的文件目录是D:/test/main.py
,而train.py
的文件目录是D:/test/model/train.py
。
但是工作目录是哪个呢?我们打开vscode,可以看到terminal中也显示了一个目录D:\test
,也就是我们项目的目录,我们点一下运行,执行了一个python脚本,输出一个PS D:\test> python -u "d:/test/model/train.py"
在哪里执行的这个脚本呢?D:\test
,这就是我们的【工作目录】
工作目录可以是任何目录,只要能通过python运行就行,例如我们打开一个终端执行我们的train.py
脚本PS C:\Users\xxx> python D:\test\model\train.py
,那么工作目录就变成了C:\Users\xxx
。
读文件
python执行的时候,open函数中相对路径的会以当前的工作目录为基准。例如我们再vscode运行脚本,工作目录是D:\test
,那么就可以直接访问test目录下的所有文件以及所有子目录和子目录下的文件。
如果我们想在main.py访问data中的data.txt文件,很自然可以写出如下代码
with open('data/data.txt') as f:res = f.read()print(res)
但如果我们想在train.py中访问data.txt目录怎么办呢?你可能会用相对路径写出如下的代码
with open('../data/data.txt') as f:res = f.read()print(res)
但是会报如下错误
Traceback (most recent call last):
File “d:/test/model/train.py”, line 1, in
with open(‘…/data/data.txt’) as f:
FileNotFoundError: [Errno 2] No such file or directory: ‘…/data/data.txt’
这是因为我们执行train.py
文件的目录D:\test
,python会以工作目录为基准目录,即D:\test
,相对路径是相对于工作目录的,因此实际访问的就是D:\test/../data/data.txt
。当然就找不到了。正确的写法就是
with open('data/data.txt') as f:res = f.read()print(res)
写文件
我们训练了一个模型,想要把最终的结果保存在model目录中,该怎么办呢?工作目录依然是D:\test
。下面这种写法依然是错误的
with open('tf.pb','w') as f:f.write('hello world')
一定要明白相对路径是相对于工作目录来说的,我们执行命令的路径是D:\test
,因此最终写入的地方就是D:\test\tf.pb
,而不是model文件夹,正确的写法如下
with open('model/tf.pb','w') as f:f.write('hello world')
切换工作目录
如果我们把工作目录换掉了,上面的路径就都不对了,例如在C:\users\xxx
目录下执行python命令,那么上面的路径就就变成了C:\users\xxx\data\data.txt
或者C:\users\xxx\model\tf.pb
了,非常的不好用。
- 查看当前工作目录
os.getcwd()
- 切换工作目录 os.chdir(path)
修改train.py和main.py为
import os
cur_dir = os.getcwd()
print(cur_dir)
然后我们打开个终端执行两个脚本
PS C:\Users\xxx> python d:/test/model/train.py
train.py work dir = C:\Users\xxx
PS C:\Users\xxx> python d:/test/main.py
main.py work dir = C:\Users\xxx
发现他们的工作目录都是一样的,重新修改main.py和train.py,并且切换工作目录
# mian.py
import os
cur_dir = os.getcwd()
print("old work dir = ", cur_dir)
os.chdir(r'D:\\test')
cur_dir = os.getcwd()
print("new work dir = ", cur_dir)
with open('data/data.txt') as f:res = f.read()print(res)
# train.py
import os
cur_dir = os.getcwd()
print("old work dir = ", cur_dir)
os.chdir(r'D:\\test')
cur_dir = os.getcwd()
print("new work dir = ", cur_dir)
with open('model/tf.pb','w') as f:f.write('hello world')
PS C:\Users\xxx> python d:/test/main.py
main.py old work dir = C:\Users\xxx
main.py new work dir = D:\test
hello world
绝对路径
我个人喜欢以执行文件的路径作为相对目录的基准。例如执行main.py文件的时候,喜欢以main.py所在的目录D:\test
为基准,执行train.py的时候,喜欢以train.py所在的目录D:\test\model
为基准,这个时候我们可以先获取文件的绝对路径,然后根据这个路径拼接出我们想要的路径来, os.path.abspath(__file__)
可以获取文件的绝对路径,
# main.py
import os
file_path = os.path.abspath(__file__)
file_dir = os.path.dirname(file_path)
print('file_dir=',file_dir)print("cur work dir = ", os.getcwd())data_path = os.path.join(file_dir, 'data/data.txt')
print('data_path=',data_path)
with open(data_path,'r') as f:res = f.read()print(res)
同样
# train.py
import os
file_path = os.path.abspath(__file__)
file_dir = os.path.dirname(file_path)
print('file_dir=',file_dir)print("cur work dir = ", os.getcwd())
#
model_path = os.path.join(file_dir, 'tf.pb')
print('model_path=',model_path)
with open(model_path,'w') as f:f.write('hello world')
PS C:\Users\xxx> python d:/test/model/train.py
file_dir= d:\test\model
cur work dir = C:\Users\xxx
model_path= d:\test\model\tf.pb
很直观了,我们根据文件的目录拼接出我们想要的目录,然后执行读写操作。
导入自定义包/文件
我们util目录中有一个view.py的文件,里面包含了一些工具类和方法
# view.py
class View:def __init__(self, x, y):self.x = xself.y = y
我们想要在train.py中调用该怎么办呢?
import util.view import View
我们以D:\test
为工作目录,执行train.py文件,嘿嘿
Traceback (most recent call last):
File “d:/test/model/train.py”, line 1, in
from util.view import View
ModuleNotFoundError: No module named ‘util’
这是因为python在导入包的时候import xxx
是以文件路径为基准的,即以train.py为基准,发现train.py的目录中并没有util子目录,因此导入失败。聪明的你做了一个简单的修改
import ..util.view import View
发现报了另一个错误
Traceback (most recent call last):
File “d:/test/model/train.py”, line 1, in
from …util.view import View
ValueError: attempted relative import beyond top-level package
这是因为python规定顶层模块不能作为package,我们执行的是train.py文件,那么train.py所在的目录就是顶层模块了,train.py相对导入的的目录不在超出了train.py所在目录,因此导入失败。换句话说就是相对导入只能导入同一个package下的子package或module。
# main.py
import model.train
#train.py
import util.view import View
这种方式依然会报错,虽然我们执行的时main.py文件,但是导入model.train的时候依然会执行train.py文件。
总结一下:
- 相对路径导入时是以当前文件为基准的,当前文件所在的目录就是顶层模块目录
- 相对导入模块不能超出顶层目录,意味者相对导入只能导入当前文件所在目录下的模块或者子package
非常的疑惑,什么时候可以使用
..
呢
包查询路径
相对路径只能导入同一package下的module。要导入不同package下的module可以使用绝对路径。这就非常奇怪了,我们安装的三方库为什么可以在任意文件导入呢?这就不得不说python的库查询机制,python回去默认的一些地方查找安装的package,具体可以通过sys.path来查看
import sysfor path in sys.path:print(path)
d:\test\model
D:\soft\python3\python37.zip
D:\soft\python3\DLLs
D:\soft\python3\lib
D:\soft\python3
C:\Users\xxx\AppData\Roaming\Python\Python37\site-packages
C:\Users\xxx\AppData\Roaming\Python\Python37\site-packages\win32
C:\Users\x\xxAppData\Roaming\Python\Python37\site-packages\win32\lib
C:\Users\x\xxAppData\Roaming\Python\Python37\site-packages\Pythonwin
D:\soft\python3\lib\site-packages
可以看到除了第一条路径,其余都是跟python的默认安装路径有关。python会按顺序从这些路径里面查找我们安装的package,越靠前的优先级越高。例如我们导入import os
这个库优先从项目路径d:\test
查找os的库,没有找到就接着从第二个路径查找,一直找到D:\soft\python3\Lib
发现有os的库,然后导入。如果我们自己的项目中有一个os的库,就会优先使用项目中的,替换掉lib里面的。
sys.path绝对路径导入自己的包
我们把自己的package也加入到sys.path
中,python就可以找到了,一种简单的方法就是
#train.py
import os
import sys
cur_dir = os.path.dirname(os.path.abspath(__file__))# 直接导入会找不到模块
#import util.view# util模块在test目录下,我们把test目录添加到sys.path中
sys.path.append(os.path.dirname(cur_dir))for path in sys.path:print(path)import util.view# nlp在model下面,sys.path的第一个路径就是d:\test\model
# 可以在d:\test\model下面发现有一个nlp的package,导入成功
from nlp.bert import BERT
sys.path相对路径导入自己的包
sys.path添加相对路径的时候,以哪个目录为基准目录呢?答案是【工作目录】,我们是在d:\test
目录下执行的命令train.py,所以工作目录就是d:\test
,而util
包就是在d:\test
下面的,所以我们
#train.py
import sys
sys.path.append(".")
for path in sys.path:print(path)
import util.view
忽略python自己的目录,我们可以看到当前有sys.path有两个目录,第一个是d:\test\model
,也就是【文件路径】,python会自动把执行的文件的路径加进来,所以文件目录下的所有package和module都可以通过相对目录的方式找到。第二个是一个.
,这个就是工作目录。因为我们使用的是相对路径导入,而相对路径的基准目录就是d:\test
,.
代表的就是基准目录。
d:\test\model
.
使用绝对路径打印更直观一些
# train.py
import sys
import os
sys.path.append(".")
for path in sys.path:print(os.path.abspath(path))
import util.view
d:\test\model
d:\test
d:\test
添加到了sys.path
中,因此d:\test
下面的package就都可以访问到了。很明显相对路径很不好用,当我们把工作目录切换到C:\users\xxx
的时候,就又找不到了
PS C:\Users\xxx> python d:/test/model/train.py
d:\test\model
D:\soft\python3\python37.zip
D:\soft\python3\DLLs
D:\soft\python3\lib
D:\soft\python3
C:\Users\xxx\AppData\Roaming\Python\Python37\site-packages
C:\Users\xxx\AppData\Roaming\Python\Python37\site-packages\win32
C:\Users\xxx\AppData\Roaming\Python\Python37\site-packages\win32\lib
C:\Users\xxx\AppData\Roaming\Python\Python37\site-packages\Pythonwin
D:\soft\python3\lib\site-packages
C:\Users\xxx
Traceback (most recent call last):
File “d:/test/model/train.py”, line 6, in
import util.view
ModuleNotFoundError: No module named ‘util’
所以我们最好使用绝对路径来添加
小结
核心诉求就是找到package,为什么会找不到我们自己定义的package呢?因为没有把路径添加到python的包搜索路径里面,怎么添加呢?使用sys.path.append
添加。定位到package的绝对路径,然后添加进去。
相关文章:

python工作目录与文件目录
工作目录 文件目录:文件所在的目录 工作目录:执行python命令所在的目录 D:. | main.py | ---data | data.txt | ---model | | model.py | | train.py | | __init__.py | | | ---nlp | | | bert.py | …...

可信和可解释的大语言模型推理-RoG
大型语言模型(LLM)在复杂任务中表现出令人印象深刻的推理能力。然而,LLM在推理过程中缺乏最新的知识和经验,这可能导致不正确的推理过程,降低他们的表现和可信度。知识图谱(Knowledge graphs, KGs)以结构化的形式存储了…...

秋招季的策略与行动指南:提前布局,高效备战,精准出击
6月即将进入尾声,一年一度的秋季招聘季正在热火进行中。对于即将毕业的学生和寻求职业发展的职场人士来说,秋招是一个不容错过的黄金时期。 秋招的序幕通常在6月至9月间拉开,名企们纷纷开启网申的大门。在此期间,求职备战是一个系…...
Java并发编程-wait与notify详解及案例实战
文章目录 概述wait()notify()作用注意事项用wait与notify手写一个内存队列wait与notify的底层原理:monitor以及wait_setMonitor(监视器)Wait Set(等待集合)Wait() 原理Notify() / NotifyAll() 原理注意事项wait与notify在代码中使用时的注意事项总结案例实战:基于wait与not…...

204.贪心算法:分发饼干(力扣)
以下来源于代码随想录 class Solution { public:int findContentChildren(vector<int>& g, vector<int>& s) {// 对孩子的胃口进行排序sort(g.begin(), g.end());// 对饼干的尺寸进行排序sort(s.begin(), s.end());int index s.size() - 1; // 从最大的饼…...

AI奥林匹克竞赛:Claude-3.5-Sonnet对决GPT-4o,谁是最聪明的AI?
目录 实验设置 评估对象 评估方法 结果与分析 针对学科的细粒度分析 GPT-4o vs. Claude-3.5-Sonnet GPT-4V vs. Gemini-1.5-Pro 结论 AI技术日新月异,Anthropic公司最新发布的Claude-3.5-Sonnet因在知识型推理、数学推理、编程任务及视觉推理等任务上设立新…...
【C++】const修饰成员函数
const修饰成员函数 常函数: 成员函数后加const后我们称为这个函数为常函数 常函数内不可以修改成员属性 成员属性声明时加关键字mutable后,在常函数中依然可以修改 class Animal { public:void fun1(){//这是一个普通的成员函数 }void fun2…...

基于模糊神经网络的时间序列预测(以hopkinsirandeath数据集为例,MATLAB)
模糊神经网络从提出发展到今天,主要有三种形式:算术神经网络、逻辑模糊神经网络和混合模糊神经网络。算术神经网络是最基本的,它主要是对输入量进行模糊化,且网络结构中的权重也是模糊权重;逻辑模糊神经网络的主要特点是模糊权值可…...

Java web应用性能分析之【prometheus监控K8s指标说明】
常规k8s的监控指标 单独 1、集群维度 集群状态集群节点数节点状态(正常、不可达、未知)节点的资源使用率(CPU、内存、IO等) 2、应用维度 应用响应时间 应用的错误率 应用的请求量 3、系统和集群组件维度 API服务器状态控…...
Spring Boot中的应用配置文件管理
Spring Boot中的应用配置文件管理 大家好,我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编,也是冬天不穿秋裤,天冷也要风度的程序猿!今天我们将深入探讨Spring Boot中的应用配置文件管理。在现代的软件开发中&am…...

SCCB协议介绍,以及与IIC协议对比
在之前的文章里已经介绍了IIC协议:iic通信协议 这篇内容主要介绍一下SCCB协议。 文章目录 SCCB协议:SCCB时序图iic时序图SCCB时序 VS IIC时序 总:SCCB协议常用在摄像头配置上面,例如OV5640摄像头,和IIC协议很相似&…...

K8S基础简介
用于自动部署,扩展和管理容器化应用程序的开源系统。 功能: 服务发现和负载均衡; 存储编排; 自动部署和回滚; 自动二进制打包; 自我修复; 密钥与配置管理; 1. K8S组件 主从方式架…...

Studying-代码随想录训练营day24| 93.复原IP地址、78.子集、90.子集II
第24天,回溯算法part03,牢记回溯三部曲,掌握树形结构结题方法💪 目录 93.复原IP地址 78.子集 90.子集II 总结 93.复原IP地址 文档讲解:代码随想录复原IP地址 视频讲解:手撕复原IP地址 题目࿱…...

2024《汽车出海全产业数据安全合规发展白皮书》下载
随着中国制造向中国智造目标的迈进,中国汽车正以前所未有的速度和质量,在全球市场上开疆拓土。不过,在中国汽车加快出海步伐的过程中,数据安全合规风险管理成为车企不容忽视的课题。 6月25日,在中国(上海&…...

nvm安装以及idea下vue启动项目过程和注意事项
注意1:nvm版本不要太低,1.1.7会出现下面这个问题,建议1.1.10及其以上版本 然后安装这个教程安装nvm和node.js 链接: nvm安装教程(一篇文章所有问题全搞定,非常详细) 注意2:上面的教程有一步骤…...
Java SPI服务发现与扩展的利器
Java中,为了实现模块之间的解耦和可扩展性,我们常常需要一种机制来动态加载和替换实现。Java SPI就是这样一种机制,它允许我们在不修改原有代码的情况下,为接口添加新的实现,并在运行时动态加载它们。 SPI,…...
Ansible的Playbook
Playbook 特点 playbook 剧本是由一个或多个"play"组成的列表play的主要功能在于将预定义的一组主机,装扮成事先通过ansible中的task定义好的任务角色。Task实际是调用ansible的一个module,将多个play组织在一个playbook中,即可以让…...

多平台自动养号【开心版】偷偷使用就行了!
大家好,今天我无意间发现了一款【多平台自动养号工具】,看了一下里面的功能还是挺全面的,包含了【抖音,快手,小红薯】还有一些截流功能 虽然这款工具功能强大,但美中不足的是需要付费的。但别担心…...
Android与JavaScript的交互,以实现从WebView中打开原生页面并传递参数
在Android应用中,实现Android与JavaScript的交互,以实现从WebView中打开原生页面并传递参数,可以通过以下详细步骤完成: 1. 准备工作 添加WebView至布局:在你的Activity或Fragment的XML布局文件中加入WebView控件。 …...
信息(文字、图像、音频、视频等)在计算机中是如何存储及显示的
信息(文字、图像、音频、视频等)在计算机中是如何存储及显示的 图片的存储图片的文件格式像素数据的二进制表示存储和处理显示总结 图片的显示4. 像素点控制具体的像素控制过程示例总结 如题,这里以图片为例。 图片的存储 计算机桌面上的一…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?
Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以? 在 Golang 的面试中,map 类型的使用是一个常见的考点,其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...

Appium+python自动化(十六)- ADB命令
简介 Android 调试桥(adb)是多种用途的工具,该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具,其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利,如安装和调试…...

从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...

【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...
三维GIS开发cesium智慧地铁教程(5)Cesium相机控制
一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点: 路径验证:确保相对路径.…...
linux 错误码总结
1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解
本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说,直接开始吧! 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...