Python 在 window 下和 linux 下使用 os,pathlib 导入自定义模块的异同

快速使用

对于模块和自己写的脚本不在同一个目录下,在脚本开头加 sys.path.append(‘xxx’):

import sys
sys.path.append('引用模块的地址')

这种方法是内运行时修改,脚本运行后就会失效的。
注意:如果要使用 import 导入函数,请一定在要导入的文件所在目录下加上"__init__.py"文件,它可以是空的,作用是将该目录变为 package 。但直接填地址不利于项目移植,下面看一下如何使用 os 或 pathlib 导入自己的模块通用方法。

一、首先看目录结构

在windows cmd 或 pycharm terminal 下使用 tree /F 命令递归查看所有文件,使用 tree /A 只查看文件夹。

E:\>tree project /F

在这里插入图片描述
linux 下使用 tree 命令,没有的需要自行安装

[root  project]# tree

├── __init__.py
├── model1
│ ├── file1.py
│ └──__init__.py
├── model2
│ ├── file2.py
│ └── __init__.py
└── setting.py

解释:project 项目下有一个 setting.py 文件和一个 __init__.py 文件,两个 model1 和 model2 文件夹,文件夹下分别有一个 __init__.py 和 file1.py / file2.py 文件。

二、model2 下的 file2.py 获取当前文件位置

1、使用 os 方法

import os
print(os.path.abspath(__file__))
# windows 下输出
# E:\project\model2\file2.py
# linux 下输出
# /project/model2/file2.py

2、使用 pathlib 方法

from pathlib import Path
print(Path(__file__))
# windows 下输出
# E:\project\model2\file2.py
# linux 下输出
# file2.py

在 linux 下并不是绝对路径,我们应该使用 .resolve() 方法取绝对路径

from pathlib import Path
print(Path(__file__).resolve())
# /project/model2/file2.py

三、model2 下的 file2.py 获取当前目录位置

1、使用 os 方法

import os
print(os.path.dirname(os.path.abspath(__file__)))
# windows 下输出
# E:\project\model2
# linux 下输出
# /project/model2

2、使用 pathlib 方法

from pathlib import Path
print(Path(__file__).resolve().parent)
# windows 下输出
# E:\project\model2
# linux 下输出
# /project/model2
# 注意这个坑
print(Path.cwd())
# windows 下,因为我是在 pycharm 里执行的
# E:\project\model2
# 而在 linux 下,我在根目录下执行
# /
# 所以最好不要用Path.cwd()去获取绝对路径!!!因为它是获取你运行命令的位置!!!

四、model2 下的 file2.py 获取上级目录

1、使用 os 方法

import os
print(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
# windows 下输出
# E:\project
# linux 下输出
# /project

2、使用 pathlib 方法

from pathlib import Path
print(Path(__file__).resolve().parent.parent)
# windows 下输出
# E:\project
# linux 下输出
# /project

五、将路径加入到 sys.path模块

将路径加入到 sys.path模块下,才能完成路径导入到运行环境中,否则会报 No module named “xxx”,这样会将 project 这层视为根目录,这和 Pycharm 将 project 设为项目是一致的,由于使用习惯了 Pycharm,项目都是相对引用。当项目移植到 linux 环境下,就各种报 No module named “xxx” 错误,就是因为执行的位置不在 project 下,必须要使用绝对路径!!!将要导入的模块加入到运行环境中。
假如在 model2 下的 file2.py 想使用:
1、 model1 下的 file1.py 的方法或类;
2、setting.py 配置文件的属性

file1.py

def test(self):
    print("This is file1.py")

setting.py

HOST = '127.0.0.1'
PORT = 8080

1、在 model2 下的 file2.py 使用 os 方法调用

import os
import sys
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(BASE_DIR)
from setting import HOST, PORT
from model1 import file1

print(f"{HOST}:{PORT}")
file1.test()
# windows 和 linux 下一致
# 127.0.0.1:8080
# This is file1.py

2、在 model2 下的 file2.py 使用 pathlib 方法调用

import sys
from pathlib import Path
BASE_DIR = Path(__file__).resolve().parent.parent
sys.path.append(BASE_DIR)
from setting import HOST, PORT
from model1 import file1

print(f"{HOST}:{PORT}")
file1.test()
# windows 下输出 
# 127.0.0.1:8080
# This is file1.py

linux 下报 ModuleNotFoundError: No module named ‘setting’ 错误
原因分析:
BASE_DIR 在 windows 下打印类型 print(type(BASE_DIR)),为 <class ‘pathlib.WindowsPath’> ,并不是 str 类型但确执行成功了。。。而在 linux 下打印类型 print(type(BASE_DIR)),为 <class ‘pathlib.PosixPath’>,应使用 str() 转义。

sys.path.append(str(BASE_DIR))

六、总结:
两种获取上层目录方法,费这么大劲就是为了项目移植到别的地方依旧能执行。
os 方法:

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

pathlib 方法:

BASE_DIR = Path(__file__).resolve().parent.parent

添加到 sys.path

sys.path.append(str(BASE_DIR))

PS :关于 WindowsPath,PosixPath 的(继承)关系,官方文档一个图,如下:
在这里插入图片描述
箭头连接的是有继承关系的两个类,WindowsPath,PosixPath 继承自 Path,即前者是后者的子类。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值