【问题标题】:Python Importing In-between FoldersPython导入中间文件夹
【发布时间】:2017-02-17 18:55:55
【问题描述】:

事前注意:这适用于我在 Python 3.6.0 中的文件,但是 Python 3.x 领域中的任何解决方案都是可行的!

导入中间文件夹

我目前在 Windows 上(没关系)并保存一个目录系统,如图所示:

Python Projects (Irrelevant)
+- Some Project (Irrelevant)
+- Some other abandoned Project (Irrelevant)
|
| (Some space to put some thought on perspectives...)
|
+- Current Project
    +- game.py             <-(acting as a game-launcher)
    +- __init__.py         <-(for packaging purposes)
    +- main                <-(folder)
        +- menu.py
        +- __init__.py
        +- chapters        <-(folder)
            +- chap1a.py   <-(Irrelevant)
    +- misc                <-(folder)
        +- func.py
        +- __init__.py

我一直在尝试几种导入方法,包括:
1. __import__ 方法本身
2. 将所有文件放在一个文件夹中并在它们之间导入(确实有效,但我正在寻找一种更“Pythonic”的方法)
3. 执行相关导入并重新调整sys.path以指导导入过程
4. 使用from &lt;whatever folder&gt; import &lt;file&gt;
5. 使用from &lt;file&gt; import &lt;class or function&gt;(可行,但我无法解决“文件夹之间”问题)
6. 将__all__ = ["filename", "filename"] 放入__init__.py
7. 使用folder.folder.file &lt;attribute?&gt; 语法导入

...以及更多最终使我失败的方法。 (也许我没有那么那么幸运?)

再深入一点(我尝试过的...)

当我的所有工作最初都是用 Python 2.7 编程并基于 Raspberry Pi(啊,旧记忆)时,我使用的原始导入方法包括:
- 将__init__.py's 放在我所有的子文件夹中,然后像这样导入:import main.menu
- 导入时另外使用细节:from misc.func import &lt;function&gt;
- 将所有文件放在一个文件夹中然后导入(那是我转移到文件夹导入的时候,作为一种使事情更整洁的方法)

上面的工作非常出色。但是……现在语法(和标准)有点不同,你也许能看到我的麻烦。

我已尝试附加导入过程将采用的路径:

#Python
import sys
sys.path.append("/Current Folder/main/menu.py") #Example
import menu

,接收NameErrors 或ModuleNotFoundErrors:

Traceback (most recent call last):
 File "C:\Users\~\Documents\PythonProjects\CurrentProject\game.py", line 11, in <module>
  import menu
ModuleNotFoundError: No module named 'menu'

我现在必须扩展单个函数导入,将它们转换为文件夹导入(远离通配符导入)。一个例子是 game.py 文件,它(假设)使用:import main.menuimport misc.func

我的这种“奇怪”的文件夹命名约定也导致了以下问题:

这些都是干什么用的?

用户将通过执行game.py 文件(或Windows / Mac 可执行文件)开始游戏,该文件从“misc”文件夹:func.py 和“main”:menu.py 导入。
Game-launcher 将控制权交给 Main-menu 文件,该文件显示(你明白了!)主菜单。如果用户退出,它将执行sys.exit(0)。但是,如果他们玩游戏,它会然后导入并播放chap.py 文件(章节文件)。
一旦该特定章节文件完成,它可能会将控制权交还给menu.py,这将然后提供退出或播放更多章节文件的选项。

令人难以置信,我知道。如果有人有比我过去四个月所做的更好的解决方案 - 请赐教,我迫切需要更新我的“知识库”
谢谢。

【问题讨论】:

  • 您尝试过的大多数事情应该都可以正常工作,尽管并非所有事情都是一个好主意。你一定做错了什么你没有向我们展示。向我们展示具体的失败代码并具体告诉我们它是如何失败的,包括完整的错误消息和堆栈跟踪(如果有的话)。
  • 另外,这个设置与大量其他 Python 导入问题没有什么特别或独特的区别。
  • @user2357112 我的“失败代码”现在不可用 - 因为我有删除它的“绝对好主意”,然后用我从这里学到或学习的内容替换它。但我可以编辑我的帖子以深入展示我所做的事情。
  • 然后写一个超级简单的例子,测试它,然后给我们看。

标签: python-3.x python-import


【解决方案1】:

对于您向我们展示的具体尝试:

#Python
import sys
sys.path.append("/Current Folder/main/menu.py") #Example
import menu

正确的做法是使用import main.menu 并将该模块中的内容用作main.menu.whateverfrom main import menu 并使用menu.whatever,而不是与sys.path 混淆。


至于为什么您尝试的方法不起作用,sys.path 不是那样起作用的。它列出了 Python 搜索模块内容的 文件夹,而不是本身实现模块的文件或文件夹。如果您在路径上放置了.../main 而不是.../main/menu.py,那么import menu 就会成功。

但是,以这种方式与sys.path 搞混会产生你真的不想处理的各种其他令人讨厌的后果,尤其是如果你还不具备正确使用常规导入的知识的话。您不希望以同一模块的 3 个独立的、微妙不同的副本结束,从同一个文件创建,或者搞砸您的 sys.path 的所有其他恐怖。不要这样做。

【讨论】:

  • 致您的第一部分...如果我要将整个主菜单文件包装到一个函数中,然后从游戏启动器中调用它:那会起作用,对吗?正如你所说,我可以做到main.menu.&lt;function&gt;。如果是这样,那就酷。
  • 我已经尝试了几天(是的,我花了那么长时间),我似乎已经破解了它 - 事实证明将所有内容包装在一个函数中并进行调用就可以了。谢谢!
猜你喜欢
  • 1970-01-01
  • 2018-08-19
  • 1970-01-01
  • 2013-02-19
  • 2020-04-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-28
相关资源
最近更新 更多