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:\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 = 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文件。
总结一下:

  1. 相对路径导入时是以当前文件为基准的,当前文件所在的目录就是顶层模块目录
  2. 相对导入模块不能超出顶层目录,意味者相对导入只能导入当前文件所在目录下的模块或者子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的绝对路径,然后添加进去。

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

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

相关文章

计算机网络期末复习(大题+小题)

计算机网络期末复习 一、计算机网络概述 Point 1 计算机网络就是以传输信息为基本目的,用通信线路和通信设备将多个计算机连接起来的计算机系统的集合。由自治的计算机互联起来的结合体。 Point 2 按网络的覆盖范围进行分类 (1)局域网*…

人机交互新维度|硕博电子发布双编码器操作面板、无线操作面板等新品

6月15日,硕博电子召开了一场新品发布会,向业界展示了多项前沿技术成果,其中备受瞩目的当属SPM-KEYP-D08双编码器操作面板、SPM-KEYP-D16W无线操作面板、SPR-HT-XK12A无线手持发射端以及SPQ-WT-B01洒水车专用控制面板。这些创新产品的亮相&…

文心一言 VS 讯飞星火 VS chatgpt (292)-- 算法导论21.3 5题

五、证明:任何具有 m 个 MAKE-SET、UNION 和 FIND-SET 操作的序列,这里所有的 LINK 操作都出现在 FIND-SET 操作之前,如果同时使用路径压缩和按秩合并启发式策略,则这些操作只需 O(m) 的时间。在同样情况下,如果只使用…

Class Constructors and Destructors (类的构造函数和析构函数)

Class Constructors and Destructors [类的构造函数和析构函数] 1. Declaring and Defining Constructors (声明和定义构造函数)2. Using Constructors (使用构造函数)3. Default Constructors (默认构造函数)4. Destructors (析构函数)5. Improving the Stock Class (改进 Sto…

前端小案例,用锚点(哈希值)实现Tab组件切换

在前端开发的世界里,使用现代化的技术和方法来实现常见的组件是非常重要的。今天,我们将通过一个具体的案例来展示如何使用现代化的CSS和ES6来创建一个优雅且功能丰富的Tab组件。本文将详细介绍实现思路、代码分析,并提供一些实用的开发技巧。…

25 防火墙基础操作

1 防火墙进入WEB页面操作 华三防火墙的默认用户:admin/密码:admin 将IP地址改在同一网段的信息 在防火墙的管理地址 GE/0/0/1:192.168.0.1 主机的地址是:192.168.0.101 思考一下为什么Ping不通 security-zone name Management import interface GigabitEthernet1/…

音视频开发34 FFmpeg 编码- 将h264和acc文件打包成flv文件

FFmpeg合成流程 示例本程序会⽣成⼀个合成的⾳频和视频流,并将它们编码和封装输出到输出⽂件,输出格式是根据⽂件 扩展名⾃动猜测的。 示例的流程图如下所示。 ffmpeg 的 Mux 主要分为 三步操作: avformat_write_header : 写⽂…

Qt WPS(有源码)

项目源码地址:WPS完整源码 一.项目详情 该项目仿照WPS,实现了部分的功能,能够很方便对文本和HTML进行修改,并且有打印功能,可以很方便的生成PDF。 应用界面 项目架构分析 这个项目主要可分为两个部分,一…

使用RNN模型构建人名分类器

使用RNN模型构建人名分类器 1 项目需求和实现分析 短文本分类问题 2 数据处理三部曲 场景1:数据处理三部曲示意图 场景2:三个字母onehot编码形状分析 3 构建RNN模型 4 构建训练函数并进行训练 - 有关模型、损失函数、优化器三者在pytorch中的表示 5…

叶老师的新水杯c++

题目描述 最近叶老师换了个带吸管的水杯。 贝贝发现当叶老师使用带吸管的水杯时,每天会喝 x 毫升的水。而使用不带吸管的水杯时,每天会喝 y 毫升的水。 请问在 n 天的时间内,叶老师喝水量的上限与下限相差多少? 输入 第一行为…

聚焦Python分布式爬虫必学框架Scrapy打造搜索引擎(一)

Scrapy综述 Scrapy总体架构 Scrapy架构图(绿线是数据流向) 适用于海量静态页面的数据下载 Scrapy Engine(引擎): 负责Spider、ItemPipeline、Downloader、Scheduler中间的通讯,信号、数据传递等。 Scheduler(调度器): 它负责接受引擎发送过来的Request请求&…

ELK 企业实战7

ELKkafkafilebeat企业内部日志分析系统 1、组件介绍 1、Elasticsearch: 是一个基于Lucene的搜索服务器。提供搜集、分析、存储数据三大功能。它提供了一个分布式多用户能力的全文搜索引擎,基于RESTful web接口。Elasticsearch是用Java开发的&#xff…

FastAPI教程——部署

部署 部署FastAPI应用程序相对容易。 部署是什么意思 部署应用程序意味着执行必要的步骤以使其可供用户使用。 对于Web API来说,通常涉及将上传到云服务器中,搭配一个性能和稳定性都不错的服务器程序,以便你的用户可以高效地访问你的应用…

智慧校园-报修管理系统总体概述

智慧校园报修管理系统是专为优化教育机构内部维修报障流程而设计的信息化解决方案,它通过集成现代信息技术,为校园设施的维护管理带来革新。该系统以用户友好和高效运作为核心,确保了从报修请求提交到问题解决的每一个步骤都顺畅无阻。 师生或…

分享画布绘制矩形

简介 实现功能&#xff0c;在画布上绘制矩形&#xff0c;移动矩形。 在线演示 绘制矩形 实现代码 <!DOCTYPE html><html><head> <title>绘制矩形</title> </head><body><div style"margin: 10px"><input typ…

FastDFS部署

版本介绍 安装fastdfs共需要俩个安装包 fastdfs-5.05.tar.gz libfastcommon-1.0.7.tar.gz编译安装 libfastcommon tar -xvf libfastcommon-1.0.7.tar.gz cd libfastcommon-1.0.7 make.sh make.sh install 3. 设置软链接 libfastcommon.so默认安装到了/usr/lib64/libfastcommon.…

5-linux文件路径与文件目录系统

目录 ①文件路径 目录跳转 绝对路径与相对路径 ②文件目录系统 目录系统组成 目录命名规则 命令补充 ls命令补充 file filename查看文件类型 less查看文本文件 ①文件路径 目录跳转 pwd:查看当前工作目录。 cd:改变目录。 ls:列出目录内容。 [root########## ~]# …

某易六月实习笔试

第一题 下面代码需要更改的地方已指出。 解题思路 模拟题&#xff0c;用双指针记录双方当前式神&#xff0c;再记录一下当前谁先手&#xff0c;直到有一方指针越界。 把下面代码now1变为now(now1)%2就行。 第二题 解题思路 01背包变种&#xff0c;只是背包的容量变为多个维度…

CLAY或许是今年最值得期待的3D生成模型,号称质量最好+布线最好+支持的输入模态最多+支持材质生成。

CLAY是一种大规模可控生成模型,用于创建高质量的3D资产,它结合了多分辨率变分自编码器和简化的潜在扩散变压器,通过多种输入形式生成详细的3D几何结构和物理渲染材质。 CLAY或许是今年最值得期待的3D生成模型,号称质量最好+布线最好+支持的输入模态最多+支持材质生成。 相…

vue2+three.js实现火焰效果

// 火焰getFireMaterial() {const vertex ${ShaderChunk.logdepthbuf_pars_vertex} bool isPerspectiveMatrix(mat4) {return true; } varying vec4 m_pos; varying vec2 vUv; varying vec3 _flame; uniform float uTime; vec2 hash( vec2 p ){p vec2( dot(p,vec2(150.1,350…