好吧,我相信这是一个非常愚蠢的问题,应该已经回答过很多次了.但我找不到任何好的解决方案,这对我来说是有效的.

我有一个包裹,就叫它my_pack吧.其中包含以下文件:

  • __init__.py:
import A
  • A.py:
import B
def A():
   B.B()
if __name__=='__main__':
   A()
  • B.py:
def B():
   print('B Called')

我想:

  • 使用包my_pack作为独立应用程序,例如Call python3 A.py
  • 从位于不同位置的其他Python脚本导入它.
  • Don't使用PIP:应用程序将部署在嵌入式系统上,默认情况下不安装PIP.最好是,我不想仅仅因为这一点而不得不包括PIP.

Current approaches:

  • 在任何地方都使用绝对路径.这显然真的很难看,我不想这样做.
  • 创建本地(PIP)包.据我所知,要做到这一点,唯一简单的方法是使用pip.这对我的情况来说并不理想.
  • 使用相对导入并编辑每个__init__.py文件中的python路径.这很管用,但也很难看.
  • 将包添加到python路径:理论上这应该是可行的,但我在包中的相对导入方面遇到了不少麻烦.这让我想,这也不是一个好的解决方案.问题是:
    • 在包内,我宁愿不使用相对导入.只是因为我需要将所有普通导入转换为相对导入.
    • 目前,我收到一个ImportError: attempted relative import with no known parent package错误.我相信,这是可以解决的,但我不确定解决这个问题有多容易或多好.

目前,我更喜欢的解决方案是将其添加到python路径并使用相对导入.然而,我并不认为,我目前的做法是好的.我认为,应该有一个更好、更简单的解决方案.

我是不是错过了其他可能性?或者这只是一个问题,在这个问题上,Python没有很好的解决方案?

我使用的是python3.9.5

推荐答案

将包添加到Python路径并使用相对导入的首选解决方案确实是一种有效的方法.但是,您可以进行一些改进,以简化该过程并避免您提到的一些问题.以下是修改后的方法:

1. Use a main script:在包目录之外创建一个单独的脚本,我们称其为main.py,它将用作独立应用程序的入口点.

2. Update 100:修改A.py以使用相对导入而不是绝对导入.这将使它既可以作为包的一部分工作,也可以从其他脚本导入时工作.

3. Modify 100:由于B.py是一个独立的模块,没有任何依赖关系,所以它可以保持原样.

4. Set the PYTHONPATH environment variable:在运行独立应用程序之前,可以设置PYTHONPATH环境变量以包括包含包的目录.这将使Python能够正确地找到并导入包.

以下是更新后的文件 struct :

my_pack/
  __init__.py
  A.py
  B.py
main.py

每个文件的修订代码如下:

__init__.py:

from . import A

A.py:

from . import B

def A():
   B.B()

if __name__ == '__main__':
   A()

B.py:

def B():
   print('B Called')

main.py:

from my_pack import A

if __name__ == '__main__':
    A.A()

要运行独立应用程序,您需要执行python3 main.py.

从位于不同位置的其他Python脚本导入my_pack时,需要确保包含my_pack的目录包含在PYTHONPATH环境变量中.

您可以在运行脚本之前在终端中临时设置PYTHONPATH:

$ export PYTHONPATH=/path/to/my_pack:$PYTHONPATH
$ python3 my_script.py

或者,您可以在导入my_pack之前在脚本中以编程方式设置它:

import sys
import os

# Add the directory containing my_pack to PYTHONPATH
package_dir = '/path/to/my_pack'
sys.path.append(package_dir)

# Now you can import my_pack
from my_pack import A

通过遵循这种方法,您可以将包my_pack用作独立的应用程序,也可以在从其他Python脚本导入时使用包my_pack,而不需要pip或绝对路径.

Python相关问答推荐

Python Turtle:处理两个连续的事件监听器驱动游戏的两个连续屏幕功能

为什么我在这个Python脚本中看到索引错误?

使用最小值、最大值、平均值对所有列执行聚合

学习率未更新

Pandas 密集排名具有相同值,按顺序排列

使用子字符串动态更新Python DataFrame中的列

带有计数值的Pandas数据帧

在两极中实施频率编码

机器人与Pyton Minecraft服务器状态不和

如何使用bs 4从元素中提取文本

使用图片生成PDF Django rest框架

Image Font生成带有条形码Code 128的条形码时出现枕头错误OSErsor:无法打开资源

如何使用scipy从频谱图中回归多个高斯峰?

在Python中对分层父/子列表进行排序

删除任何仅包含字符(或不包含其他数字值的邮政编码)的观察

如何记录脚本输出

修复mypy错误-赋值中的类型不兼容(表达式具有类型xxx,变量具有类型yyy)

如何请求使用Python将文件下载到带有登录名的门户网站?

如何将一个动态分配的C数组转换为Numpy数组,并在C扩展模块中返回给Python

如何根据一列的值有条件地 Select 前N组?