Python 导入中间文件夹

Python Importing In-between Folders

事前注意:这将应用于我在 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 <whatever folder> import <file>
5. 使用 from <file> import <class or function>(有效,但我无法解决 'between folders' 问题)
6. 将 __all__ = ["filename", "filename"] 放在 __init__.py
中 7. 使用 folder.folder.file <attribute?> 语法导入

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

更深入一点(我试过的...)

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

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

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

#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.

我的这个 'weird' 文件夹命名约定也导致了以下问题:

这都是用来做什么的?

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

令人难以置信,我知道。如果有人有比我过去四个月一直在做的更好的解决方案 - 请赐教,我迫切需要更新我的 "Knowledge-bank"
谢谢。

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

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

正确的做法是 import main.menu 并将该模块中的内容用作 main.menu.whatever,或 from main import menu 并使用 menu.whatever,而不是乱用 sys.path.


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

但是,以这种方式搞乱 sys.path 会产生您真的不想处理的各种其他恶劣后果,尤其是在您还不具备正确使用常规导入的知识的情况下。您不希望最终得到同一模块的 3 个独立的、细微不同的副本,这些副本是从同一文件创建的,或者所有其他搞砸您的 sys.path 的恐怖事件。别这样。