导入路径 - 正确的方法?

2024-01-10

我知道有很多类似或相同的问题,但我仍然无法理解/找到使用模块的正确方法。 Python 是我最喜欢的语言,除了使用导入之外,我喜欢其中的所有内容:递归导入(当您尝试引用尚不存在的名称时)、导入路径等。

所以,我有这样的项目结构:

my_project/
    package1/
        __init__.py
        module1
        module2
    package2/
        __init__.py
        module1
        module2

Package1可以作为独立装置使用,但也有望通过进口package2。 我现在在做什么,例如,在package1.module1我写的from package1 import module2,即使用导入模块的完整路径。我这样做是因为如果我使用import module2-- 当模块从另一个包导入时,这将不起作用(package2)。我也无法使用from . import module2-- 这在运行时不起作用module1直接地。

好的,所以对于from package1 import module2 in package1.module1在两种情况下都可以工作(直接运行时package1.module1当从以下位置导入它时package2)我在开头添加这些行package1.module1:

import os, sys
currDir = os.path.dirname(os.path.realpath(__file__))
rootDir = os.path.abspath(os.path.join(currDir, '..'))
if rootDir not in sys.path: # add parent dir to paths
    sys.path.append(rootDir)

对我来说这可行,但我觉得这不是Pythonic。难道我做错了什么?

相反,我应该总是跑步吗package1.module1从项目根目录?如果是这样,从 IDE 运行它会很不方便——我需要以某种方式在其中设置路径。

更新:我尝试添加文件root.pth to package1目录内容为..。但它没有用——我猜它是有其他用途的。

结论:

  1. 始终使用绝对导入:import package1.module1

  2. 将引导程序添加到根文件夹以将某些模块作为独立脚本启动。这解决了从 IDE 运行脚本的问题,是一种 Pythonic 方法。

2007 年 4 月 22 日,布雷特·坎农 (Brett Cannon) 写道:

本 PEP 旨在改变if __name__ == "__main__": ...成语if __name__ == sys.main: ...这样你至少有机会 执行使用相对导入的包中的模块。

将此 PEP 运行到 python-ideas 上。也在那里停止了讨论 人们提出了许多新的想法。 =) 我已将它们全部列出在 被拒绝的想法部分,尽管如果有压倒性的支持 出现后,PEP 可以转向其中之一。

我对此以及任何其他建议的调整都是-1__main__机械。唯一的用例似乎是运行发生的脚本 位于模块的目录中,我一直将其视为 反模式。为了让我改变主意你必须让我相信 事实并非如此。

--吉多·范罗苏姆 http://mail.python.org/pipermail/python-3000/2007-April/006793.html


您的程序的入口点是什么?通常程序的入口点位于项目的根目录。由于它位于根目录,因此根目录中的所有模块都将是可导入的,只要有一个__init__.py文件在其中。

所以,用你的例子:

my_project/
    main.py
    package1/
        __init__.py
        module1
        module2
    package2/
        __init__.py
        module1
        module2

main.py将是您的程序的入口点。因为作为 main 执行的文件会自动放到 PYTHONPATH 上,所以package1 and package2可从顶级导入获得。

# in main.py
from package1.module1 import *
from package1.module2 import *

# in package1.module1
import module2
from package2.module1 import *

# in package2.module1 import *
import module2
from package1.module1 import *

请注意,在上面,package1 和 package2 相互依赖。情况绝对不应该如此。但这只是能够从任何地方导入的示例。

main.py也不必是什么花哨的东西。它可以非常简单:

# main.py

if __name__ == '__main__':
    from package1.module1 import SomeClass
    SomeClass().start()

我想要表达的观点是,如果一个模块需要被其他模块访问,那么该模块应该可以作为顶级导入使用。模块不应尝试将自身作为顶级导入(直接在 PYTHONPATH 上)。

这应该是相关部门的责任project如果模块直接包含在项目中,则确保可以满足所有导入。有两种方法可以做到这一点。第一种是创建引导程序文件,例如main.py在项目文件夹中。另一种方法是创建一个文件,将所有相关路径添加到 PYTHONPATH,该文件由可能存在的任何入口点加载。

例如:

# setup.py
import sys

def load():
    paths = ['/path1/','/path2/','/path3/']
    for p in path:
        sys.path.insert(0, p)

# entrypoint.py
from setup import load
load()
# continue with program

最重要的是,模块是not应该把自己放在路上。该路径应该由程序的入口点自动确定,或者由知道所有相关模块所​​在位置的安装脚本明确定义。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

导入路径 - 正确的方法? 的相关文章

  • 尽管极其懒惰,但如何在 Python 中模拟 IMAP 服务器?

    我很好奇是否有一种简单的方法来模拟 IMAP 服务器 例如imaplib模块 在Python中 without做很多工作 是否有预先存在的解决方案 理想情况下 我可以连接到现有的 IMAP 服务器 进行转储 并让模拟服务器在真实的邮箱 电子
  • Python BigQuery 存储。并行读取多个流

    我有以下玩具代码 import pandas as pd from google cloud import bigquery storage v1beta1 import os import google auth os environ G
  • Django REST序列化器:创建对象而不保存

    我已经开始使用 Django REST 框架 我想做的是使用一些 JSON 发布请求 从中创建一个 Django 模型对象 然后使用该对象而不保存它 我的 Django 模型称为 SearchRequest 我所拥有的是 api view
  • InterfaceError:连接已关闭(使用 django + celery + Scrapy)

    当我在 Celery 任务中使用 Scrapy 解析函数 有时可能需要 10 分钟 时 我得到了这个信息 我用 姜戈 1 6 5 django celery 3 1 16 芹菜 3 1 16 psycopg2 2 5 5 我也使用了psyc
  • pandas 替换多个值

    以下是示例数据框 gt gt gt df pd DataFrame a 1 1 1 2 2 b 11 22 33 44 55 gt gt gt df a b 0 1 11 1 1 22 2 1 33 3 2 44 4 3 55 现在我想根据
  • 如何使用包含代码的“asyncio.sleep()”进行单元测试?

    我在编写 asyncio sleep 包含的单元测试时遇到问题 我要等待实际的睡眠时间吗 I used freezegun到嘲笑时间 当我尝试使用普通可调用对象运行测试时 这个库非常有用 但我找不到运行包含 asyncio sleep 的测
  • Spark的distinct()函数是否仅对每个分区中的不同元组进行洗牌

    据我了解 distinct 哈希分区 RDD 来识别唯一键 但它是否针对仅移动每个分区的不同元组进行了优化 想象一个具有以下分区的 RDD 1 2 2 1 4 2 2 1 3 3 5 4 5 5 5 在此 RDD 上的不同键上 所有重复键
  • __del__ 真的是析构函数吗?

    我主要用 C 做事情 其中 析构函数方法实际上是为了销毁所获取的资源 最近我开始使用python 这真的很有趣而且很棒 我开始了解到它有像java一样的GC 因此 没有过分强调对象所有权 构造和销毁 据我所知 init 方法对我来说在 py
  • 安装后 Anaconda 提示损坏

    我刚刚安装张量流GPU创建单独的后环境按照以下指示here https github com antoniosehk keras tensorflow windows installation 但是 安装后当我关闭提示窗口并打开新航站楼弹出
  • 在 NumPy 中获取 ndarray 的索引和值

    我有一个 ndarrayA任意维数N 我想创建一个数组B元组 数组或列表 其中第一个N每个元组中的元素是索引 最后一个元素是该索引的值A 例如 A array 1 2 3 4 5 6 Then B 0 0 1 0 1 2 0 2 3 1 0
  • NameError:名称“urllib”未定义”

    CODE import networkx as net from urllib request import urlopen def read lj friends g name fetch the friend list from Liv
  • Abaqus 将曲面转化为集合

    我一直试图在模型中找到两个表面的中心 参见照片 但未能成功 它们是元素表面 面 查询中没有选项可以查找元素表面的中心 只能查找元素集的中心 找到节点集的中心也很好 但是我的节点集没有出现在工具 gt 查询 gt 质量属性选项中 而且我找不到
  • python 集合可以包含的值的数量是否有限制?

    我正在尝试使用 python 设置作为 mysql 表中 ids 的过滤器 python集存储了所有要过滤的id 现在大约有30000个 这个数字会随着时间的推移慢慢增长 我担心python集的最大容量 它可以包含的元素数量有限制吗 您最大
  • 当玩家触摸屏幕一侧时,如何让 pygame 发出警告?

    我使用 pygame 创建了一个游戏 当玩家触摸屏幕一侧时 我想让 pygame 给出类似 你不能触摸屏幕两侧 的错误 我尝试在互联网上搜索 但没有找到任何好的结果 我想过在屏幕外添加一个方块 当玩家触摸该方块时 它会发出警告 但这花了很长
  • Python 3 中“map”类型的对象没有 len()

    我在使用 Python 3 时遇到问题 我得到了 Python 2 7 代码 目前我正在尝试更新它 我收到错误 类型错误 map 类型的对象没有 len 在这部分 str len seed candidates 在我像这样初始化它之前 se
  • 如何将 PIL 图像转换为 NumPy 数组?

    如何转换 PILImage来回转换为 NumPy 数组 这样我就可以比 PIL 进行更快的像素级转换PixelAccess允许 我可以通过以下方式将其转换为 NumPy 数组 pic Image open foo jpg pix numpy
  • 如何在 Django 中使用并发进程记录到单个文件而不使用独占锁

    给定一个在多个服务器上同时执行的 Django 应用程序 该应用程序如何记录到单个共享日志文件 在网络共享中 而不保持该文件以独占模式永久打开 当您想要利用日志流时 这种情况适用于 Windows Azure 网站上托管的 Django 应
  • 使用基于正则表达式的部分匹配来选择 Pandas 数据帧的子数据帧

    我有一个 Pandas 数据框 它有两列 一列 进程参数 列 包含字符串 另一列 值 列 包含相应的浮点值 我需要过滤出部分匹配列 过程参数 中的一组键的子数据帧 并提取与这些键匹配的数据帧的两列 df pd DataFrame Proce
  • 改变字典的哈希函数

    按照此question https stackoverflow com questions 37100390 towards understanding dictionaries 我们知道两个不同的字典 dict 1 and dict 2例
  • Python 分析:“‘select.poll’对象的‘poll’方法”是什么?

    我已经使用 python 分析了我的 python 代码cProfile模块并得到以下结果 ncalls tottime percall cumtime percall filename lineno function 13937860 9

随机推荐

  • 我希望 shell 脚本可执行但不可读

    我创建了一个脚本 我希望其他用户使用我们的共享系统 to 执行但不读取 我将权限设置为所有可执行文件 但撤销了读 写权限 x x x 1 dilletante staff 0 2013 04 02 11 42 expect sh 然而脚本无
  • 使用 lambda 表达式参数调用泛型方法的反射

    我正在寻找一种使用 lambda 表达式调用通用方法的方法 该表达式在项目数组中调用 Contains 在本例中 我使用实体框架Where方法 但该场景可以应用于其他IEnumerables 我需要通过 Reflection 调用上面代码的
  • 如何检查 SQL Server 当前池大小

    有没有办法检查 SQL Server 中当前连接池的大小 我不是在谈论最大连接池大小 而是当前池大小 假设最大池大小为 100 并且有 49 个打开的连接 它现在应该显示 51 个可用连接或 49 个已消耗连接 那么 有这样的查询吗 其中很
  • Golang写入套接字而不用担心数据不完整

    我们都知道 Write 方法不能保证从缓冲区中写入高字节 因此 使用原始 Write 方法将字节写入套接字的规范方法如下所示 how many bytes we have written written 0 for written lt l
  • 无法让 QWindow::fromWinId 正常工作

    我的 Qt 5 9 程序 在 X11 Linux 上 使用以下命令启动其他应用程序QProcess 我想控制这些应用程序生成的窗口 所以我获得了它们winId价值和用途QWindow fromWinId得到一个QWindow实例 问题是这些
  • Laravel $request->expectsJson()

    我正在为我的 Laravel 应用程序进行 Ajax 登录 我正在使用角度 http method POST url admin login headers Content Type application json data email
  • 如何读取图像上的文字?

    我需要将一些扫描文档解析为文本数据 是否可以使用某些软件解析图像上写的文本 如果是 请推荐任何此类在线实用程序或软件 也许一些 OCR 软件会有帮助 http en wikipedia org wiki Optical character
  • 忽略“证书未知”警报

    我有以下简单的 Python 脚本 import socket import ssl if name main s socket socket socket AF INET socket SOCK STREAM s bind 443 s l
  • 销毁 Bootstrap 弹出窗口时出现 Javascript 错误

    尝试随时更改引导程序弹出窗口的标题和内容 我遇到了一些麻烦 我在销毁选择器中的弹出窗口内容时遇到此问题 错误是这样的 TypeError undefined is not a function evaluating data option
  • T-SQL删除插入的记录

    我知道标题可能看起来很奇怪 但这就是我想做的 我有很多记录的表 我想获取其中一些记录并将它们插入到其他表中 像这样的东西 INSERT INTO TableNew SELECT FROM TableOld WHERE 棘手的部分是我希望我插
  • Jquery UI 工具提示不支持 html 内容

    今天 我将所有 jQuery 插件升级为 jQuery 1 9 1 我开始将 jQueryUI 工具提示与 jquery ui 1 10 2 一起使用 一切都很好 但是当我在内容中使用 HTML 标签时 在title我正在应用工具提示的元素
  • 我怎样才能使这个模式持久化?

    我正在寻找一种方法 让这种模式在出现后持久存在 正如此处所示 用户只需在 div 外部单击一下即可将其关闭
  • 如何制作一个反应本机输入,向用户提供验证状态反馈。 [有效、Printine、错误、编辑]

    我希望输入能够随着用户键入而不断更新 然后失去焦点 反馈将是输入周围的边框 1 Green when valid 2 Amber when typing and is in error state Green when valid 3 Re
  • 一面一示例 T 测试 Python

    在 Python 中 我使用 SciPy 进行单样本 t 检验 from scipy import stats one sample data 177 3 182 7 169 6 176 3 180 3 179 4 178 5 177 2
  • Checkstyles + Gradle 抛出引起:java.lang.IllegalArgumentException:给定名称 COMPACT_CTOR_DEF

    我最近将 checkstyle 插件添加到项目中以进行静态代码分析 但更新之后google style xml从最新的大师那里 我开始收到以下异常 org gradle api tasks TaskExecutionException Ex
  • grails 2.0 - 正确使用 serverURL 进行生产?

    Grails 2 0 改变了它使用 grails serverURL 进行开发和测试环境的方式 如manual http grails org doc 2 0 x guide single html upgradingFromPreviou
  • Python从视频文件中提取wav

    Related 如何使用python从视频文件中提取音频 https stackoverflow com questions 19216450 how to extract audio from a video file using pyt
  • 如何在 Obj-C 类别中“伪造”ivars (iPhone)

    Update iPhone OS 3 1 有关联的对象 然而 iPhone 模拟器却没有 如果您想在模拟器中测试关联的对象代码 您应该提交错误 请参阅我的问题here https stackoverflow com questions 19
  • 最接近的 3 点组

    是否有一种已知的 有效的算法来查找最接近的组three云中的点 这类似于最近点对问题 http en wikipedia org wiki Closest pair of points problem但我正在寻找三点而不是两点 Edit 最
  • 导入路径 - 正确的方法?

    我知道有很多类似或相同的问题 但我仍然无法理解 找到使用模块的正确方法 Python 是我最喜欢的语言 除了使用导入之外 我喜欢其中的所有内容 递归导入 当您尝试引用尚不存在的名称时 导入路径等 所以 我有这样的项目结构 my projec