python工作目录与文件目录

news2024/7/2 21:25:00

工作目录

文件目录:文件所在的目录
工作目录:执行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:\testpython会以工作目录为基准目录,即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 = x
		self.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文件。
总结一下:

  1. 相对路径导入时是以当前文件为基准的,当前文件所在的目录就是顶层模块目录
  2. 相对导入模块不能超出顶层目录,意味者相对导入只能导入当前文件所在目录下的模块或者子package

非常的疑惑,什么时候可以使用..

包查询路径

相对路径只能导入同一package下的module。要导入不同package下的module可以使用绝对路径。这就非常奇怪了,我们安装的三方库为什么可以在任意文件导入呢?这就不得不说python的库查询机制,python回去默认的一些地方查找安装的package,具体可以通过sys.path来查看

import sys

for 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的绝对路径,然后添加进去。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1880347.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

DIVE INTO DEEP LEARNING 56-60

文章目录 56 Gated Recurrent Unit(GRU)56.1 Motivation: How to focus on a sequence56.2 The concept of doors56.3 Candidate hidden state56.4 hidden state56.5 summarize56.6 QA 57 Long short-term memory network57.1 Basic concepts57.2 Long short-term memory netwo…

Linux 进程信号篇

文章目录 1. 生活中的信号2. 信号的概念3. 信号的产生3.1 系统调用3.2 软件条件3.2 异常3.3 Core和Term的区别 4. 信号的保存5. 信号的处理5.1 地址空间的进一步理解5.2 键盘输入数据的过程5.3 理解OS如何正常运行5.3.1 OS如何运行5.3.2 如何理解系统调用 5.4 内核态和用户态 6…

YOLO-V1

一、YOLO-V1整体思想与网络架构 1.1 YOLO算法整体思路解读 YOLO-V1: 经典的one-stage方法 把检测问题转化成回归问题,一个CNN就搞定了! 可以对视频进行实时检测,应用领域非常广! 核心思想: 1、预测一张图像中有哪些物…

AI大模型的崛起:第四次工业革命的前奏?

在当今这个信息爆炸的时代,人工智能(AI)大模型的崛起引起了广泛的关注和讨论。有人将其视为第四次工业革命的前奏,然而,这真的可能吗?本文将探讨这一问题,并对中国AI大模型的发展进行简要分析。…

鸿蒙开发Ability Kit(程序框架服务):【向用户申请授权】

向用户申请授权 当应用需要访问用户的隐私信息或使用系统能力时,例如获取位置信息、访问日历、使用相机拍摄照片或录制视频等,应该向用户请求授权,这部分权限是user_grant权限。 当应用申请user_grant权限时,需要完成以下步骤&a…

推荐系统三十六式学习笔记:原理篇.模型融合14|一网打尽协同过滤、矩阵分解和线性模型

目录 从特征组合说起FM模型1.原理2.模型训练3.预测阶段4.一网打尽其他模型5.FFM 总结 在上一篇文章中,我们讲到了使用逻辑回归和梯度提升决策树组合的模型融合办法,用于CTR预估,给这个组合起了个名字,叫“辑度组合”。这对组合中&…

鸿蒙开发设备管理:【@ohos.multimodalInput.inputEventClient (注入按键)】

注入按键 InputEventClient模块提供了注入按键能力。 说明: 本模块首批接口从API version 8开始支持。后续版本的新增接口,采用上角标单独标记接口的起始版本。本模块接口均为系统接口,三方应用不支持调用。 导入模块 import inputEventCli…

小白学webgl合集-绘制有透视颜色不一样的立方体

效果 原理 结合透视矩阵和视觉矩阵进行绘制 知识点 01透视矩阵 透视矩阵将视图空间中的坐标转换为裁剪空间中的坐标,使得更远的物体看起来更小。 function perspectiveMatrix(fov, aspect, near, far) {const f 1.0 / Math.tan(fov / 2);const nf 1 / (near …

C++旋转点坐标计算

/// 获取A点绕B点旋转P度后的新坐标/// </summary>/// <param name"Angle">角度</param>/// <param name"CirPoint">圆心坐标</param>/// <param name"MovePoint">移动点的坐标</param>/// <param…

(单机架设教程)3D剑踪

前言 今天给大家带来一款单机游戏的架设&#xff1a;3D剑踪 如今市面上的资源参差不齐&#xff0c;大部分的都不能运行&#xff0c;本人亲自测试&#xff0c;运行视频如下&#xff1a; 3D剑踪 搭建教程 此游戏架设不需要虚拟机&#xff0c; 我们先解压 “3D剑踪.zip” &…

【ArcGIS AddIn插件】【可用于全国水旱灾害风险普查】全网最强洪水淹没分析插件-基于8邻域种子搜索算法-有源淹没分析算法

最近有很多GIS小伙伴咨询我关于基于8邻域种子搜索算法的有源淹没分析插件的使用方法及原理&#xff0c;咱们通过这篇文章给大家详细介绍下这款插件的运行机制。 一、插件类型及适用版本 本插件属于ArcGIS AddIn工具条插件&#xff0c;基于ArcGIS Engine10.2.2的开发环境开发的&…

某度,网盘免费加速,复活!

哈喽&#xff0c;各位小伙伴们好&#xff0c;我是给大家带来各类黑科技与前沿资讯的小武。 有小伙伴反馈之前如下夸克网盘脚本的加速方法失效&#xff0c;小武今天测试&#xff0c;依旧正常使用&#xff01; 百度/迅雷/夸克&#xff0c;网盘免费加速&#xff0c;已破&#xf…

最强文生图模型Stable Diffusion 3 Medium 正式开源

Stability AI 宣布 Stable Diffusion 3 Medium 现已开源&#xff0c;是 Stable Diffusion 3 系列中最新、最先进的文本生成图像 AI 模型 —— 官方声称是 “迄今为止最先进的开源模型”&#xff0c;其性能甚至超过了 Midjourney 6。 Stable Diffusion 3 Medium 模型规格参数达到…

科普文:八大排序算法(JAVA实现)+ 自制动画 (袁厨的算法小屋)

我将我仓库里的排序算法给大家汇总整理了一下&#xff0c;写的非常非常细&#xff0c;还对每个算法制作了动画&#xff0c;一定能够对大家有所帮助&#xff0c;欢迎大家阅读。另外我也对 leetcode 上面可以用排序算法秒杀的算法题进行了总结&#xff0c;会在后面的文章中进行发…

[知识点篇]《计算机组成原理》之数据信息的表示

1、数据表示的作用 &#xff08;1&#xff09;定义&#xff1a;将数据按照某种方式组织&#xff0c;以便机器硬件能直接识别和使用。现代计算机采用二进制进行数据表示。 &#xff08;2&#xff09;数据表示考虑因素&#xff1a; 数据的类型&#xff1a; 数值/非数值、小数、…

团队任务管理跟踪软件有哪些?分享2024年值得关注的10款

本文将分享2024年值得关注的10款团队任务管理跟踪软件&#xff1a;Worktile、PingCode、Zoho Projects、Wrike、ProofHub、Connecteam、MeisterTask、Nifty、BIGContacts、Hive。 无论是小型初创企业还是庞大的跨国公司&#xff0c;高效的任务管理都能显著提升工作效率&#xf…

Linux_动、静态库

目录 一、静态库 1、静态库的概念 2、制作静态库的指令 3、制作静态库 4、链接静态库 二、动态库 1、动态库的概念 2、制作动态库的指令 3、制作动态库 4、链接动态库 5、动态库的加载 三、静态库与动态库的区别 结语 前言&#xff1a; 在Linux下大部分程序进…

颍川韩氏,来自战国七雄韩国的豪族

颍川是战国七雄韩国故土&#xff0c;韩国被秦国灭国后&#xff0c;王公贵族们除了坚决反秦的被杀了外&#xff0c;大部分都留存了下来。这些人在楚、汉反秦战争中&#xff0c;成为反秦统一战线的重要力量&#xff0c;其中两人先后被封为重新恢复的韩国的国王。 一个是横阳君韩…

240630_昇思学习打卡-Day12-Transformer中的Multiple-Head Attention

240630_昇思学习打卡-Day12-Transformer中的Multiple-Head Attention 以下为观看大佬课程及查阅资料总结所得&#xff0c;附大佬视频链接&#xff1a;Transformer中Self-Attention以及Multi-Head Attention详解_哔哩哔哩_bilibili&#xff0c;强烈建议先去看大佬视频&#xff…

【Linux】IO多路复用——select,poll,epoll的概念和使用,三种模型的特点和优缺点,epoll的工作模式

文章目录 Linux多路复用1. select1.1 select的概念1.2 select的函数使用1.3 select的优缺点 2. poll2.1 poll的概念2.2 poll的函数使用2.3 poll的优缺点 3. epoll3.1 epoll的概念3.2 epoll的函数使用3.3 epoll的优点3.4 epoll工作模式 Linux多路复用 IO多路复用是一种操作系统的…