从当前工作目录上方的目录导入模块 情况1:您不想打包您的库案例2:您想打包您的库

如何解决从当前工作目录上方的目录导入模块 情况1:您不想打包您的库案例2:您想打包您的库

首先,有很多关于stackoverflow的解决方案,但是从我尝试过的解决方案中,没有一个起作用。我正在远程计算机(Linux)上工作。我正在使用ipython解释器在dir-2/module_2.py文件中进行原型设计。另外,我试图避免使用绝对路径,因为此远程计算机中的绝对路径又长又丑陋,我希望我的代码在下载时可以在其他计算机上运行。

我的目录结构如下:

/project-dir/
            -/dir-1/
                  -/__ init__.py
                  -/module_1.py
            -/dir-2/
                  -/__ init__.py
                  -/module_2.py
                  -/module_3.py

现在,我想从module_1导入module_2。但是,此stackoverflow帖子中提到的解决方案是:link使用

sys.path.append('../..')
import module_2

不起作用。我收到错误消息:ModuleNotFoundError: No module named 'module_1'

此外,在ipython解释器中,import .module_3之内的module_2之类的错误引发:

import .module_3
       ^ SyntaxError: invalid syntax

点运算符也不应该在同一目录中工作。总的来说,我对导入机制感到很困惑。非常感谢您对最初问题的任何帮助!非常感谢!

解决方法

为什么不起作用?

如果您运行module1.py文件并要导入module2,则需要类似

sys.path.append("../dir-2")

如果您在其中使用sys.path.append("../..") then the folder you added to the path is the folder containing project-dir and there is not module2.py`文件。


语法import .module_3用于相对导入。如果您尝试执行module2.py并且它包含import .module_3,则该命令将不起作用,因为您使用module2.py作为脚本。要使用相对导入,您需要将module2.pymodule_3.py都视为模块。也就是说,其他一些文件导入module2和module2使用此语法从module3导入一些东西。

关于如何进行的建议

解决这两个问题的一种可能的解决方案是组织项目的属性和(可选地,一个好主意)打包库(即,使代码“可安装”)。然后,在安装库(在虚拟环境中工作)后,您就不需要 hacky sys.path解决方案。您将可以从任何文件夹导入库。

此外,请勿将您的模块视为脚本(请勿运行您的模块)。使用一个单独的python文件作为您的“可执行文件”(或入口点),并从那里导入您需要的所有内容。这样,您的module*.py文件中的相对导入将可以正常工作,并且您不会感到困惑。

可能是可能的目录结构

/project-dir/
            - apps/
                  - main.py
            - yourlib/
                  -/__ init__.py
                  -/dir-1/
                        -/__ init__.py
                        -/module_1.py
                  -/dir-2/
                        -/__ init__.py
                        -/module_2.py
                        -/module_3.py

请注意,yourlib文件夹以及子文件夹包含一个__init__.py文件。使用这种结构,您只需运行main.py(名称不必为main.py)。

情况1:您不想打包您的库

如果您不想打包库,则可以在sys.path.append("../")中添加main.py,以将“ project-dir/文件夹添加到路径。 }库在yourlib中是“可导入的”。您可以进行类似main.py的操作,并且它可以正常工作(并且from yourlib import module_2可以使用相对导入)。或者,您也可以直接将{ module_2文件夹中的{1}},您根本不需要更改main.py,因为在这种情况下,project-dir/将成为“工作目录”。

请注意,您还可以在sys.path内有一个project-dir/文件夹,并且要运行测试文件,可以执行与运行tests相同的操作。

案例2:您想打包您的库

先前的解决方案已经解决了您的问题,但是加倍努力会带来一些好处,例如依赖管理,无论您身在何处都无需更改project-dir。打包您的库有多种选择,由于其简单性,我将使用poetry显示一个选择。

安装诗歌后,您可以在终端中运行以下命令来创建新项目

main.py

这将创建以下文件夹结构

sys.path

然后,您可以根据需要添加poetry new mylib 文件夹,以及mylib/ - README.rst - mylib/ - __init__.py - pyproject.toml - tests 内的子文件夹(每个文件夹都有一个apps文件)。

pyproject.toml文件指定依赖项和项目元数据。您可以手动编辑和/或使用诗歌来添加新的依赖项,例如

mylib/
例如,

__init__.py添加为依赖项,并将poetry add pandas poetry add --dev mypy 添加为开发依赖项。之后,您可以运行

pandas

创建虚拟环境并在其中安装您的库。您可以使用mypy激活虚拟环境,并且可以从任何地方导入库。请注意,您可以更改库文件,而无需再次运行poetry build

最后,如果您想在PyPi中发布您的库,以供所有人查看,您可以使用

poetry shell

TL; DR

使用有组织的项目结构,在清晰的位置显示您执行的脚本。特别是,如果您执行的脚本位于模块所在文件夹的外部,则更好。另外,请勿将模块作为脚本运行(否则您不能使用相对导入)。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


依赖报错 idea导入项目后依赖报错,解决方案:https://blog.csdn.net/weixin_42420249/article/details/81191861 依赖版本报错:更换其他版本 无法下载依赖可参考:https://blog.csdn.net/weixin_42628809/a
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下 2021-12-03 13:33:33.927 ERROR 7228 [ main] o.s.b.d.LoggingFailureAnalysisReporter : *************************** APPL
错误1:gradle项目控制台输出为乱码 # 解决方案:https://blog.csdn.net/weixin_43501566/article/details/112482302 # 在gradle-wrapper.properties 添加以下内容 org.gradle.jvmargs=-Df
错误还原:在查询的过程中,传入的workType为0时,该条件不起作用 <select id="xxx"> SELECT di.id, di.name, di.work_type, di.updated... <where> <if test=&qu
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct redisServer’没有名为‘server_cpulist’的成员 redisSetCpuAffinity(server.server_cpulist); ^ server.c: 在函数‘hasActiveC
解决方案1 1、改项目中.idea/workspace.xml配置文件,增加dynamic.classpath参数 2、搜索PropertiesComponent,添加如下 <property name="dynamic.classpath" value="tru
删除根组件app.vue中的默认代码后报错:Module Error (from ./node_modules/eslint-loader/index.js): 解决方案:关闭ESlint代码检测,在项目根目录创建vue.config.js,在文件中添加 module.exports = { lin
查看spark默认的python版本 [root@master day27]# pyspark /home/software/spark-2.3.4-bin-hadoop2.7/conf/spark-env.sh: line 2: /usr/local/hadoop/bin/hadoop: No s
使用本地python环境可以成功执行 import pandas as pd import matplotlib.pyplot as plt # 设置字体 plt.rcParams['font.sans-serif'] = ['SimHei'] # 能正确显示负号 p
错误1:Request method ‘DELETE‘ not supported 错误还原:controller层有一个接口,访问该接口时报错:Request method ‘DELETE‘ not supported 错误原因:没有接收到前端传入的参数,修改为如下 参考 错误2:cannot r
错误1:启动docker镜像时报错:Error response from daemon: driver failed programming external connectivity on endpoint quirky_allen 解决方法:重启docker -> systemctl r
错误1:private field ‘xxx‘ is never assigned 按Altʾnter快捷键,选择第2项 参考:https://blog.csdn.net/shi_hong_fei_hei/article/details/88814070 错误2:启动时报错,不能找到主启动类 #
报错如下,通过源不能下载,最后警告pip需升级版本 Requirement already satisfied: pip in c:\users\ychen\appdata\local\programs\python\python310\lib\site-packages (22.0.4) Coll
错误1:maven打包报错 错误还原:使用maven打包项目时报错如下 [ERROR] Failed to execute goal org.apache.maven.plugins:maven-resources-plugin:3.2.0:resources (default-resources)
错误1:服务调用时报错 服务消费者模块assess通过openFeign调用服务提供者模块hires 如下为服务提供者模块hires的控制层接口 @RestController @RequestMapping("/hires") public class FeignControl
错误1:运行项目后报如下错误 解决方案 报错2:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1:compile (default-compile) on project sb 解决方案:在pom.
参考 错误原因 过滤器或拦截器在生效时,redisTemplate还没有注入 解决方案:在注入容器时就生效 @Component //项目运行时就注入Spring容器 public class RedisBean { @Resource private RedisTemplate<String
使用vite构建项目报错 C:\Users\ychen\work>npm init @vitejs/app @vitejs/create-app is deprecated, use npm init vite instead C:\Users\ychen\AppData\Local\npm-