Python 模块自动加载器?

Python modules autoloader?

如何自动加载保存在不同目录和子目录中的所有模块?

我看到这个answer正在使用__import__,但它仍然不是我想要的自动加载。

我的想法类似于 PHP autoloader. Even better something like Composer autoloader

从我目前收集的研究来看,autoloader 在 Python 似乎不是一个流行的东西(不能确定,因为我是 Python 的新手)。 Python 中不鼓励自动加载某些内容吗?

到目前为止我的自动加载代码,

import os
import sys

root = os.path.dirname(__file__)
sys.path.append(root + "/modules")
sys.path.append(root + "/modules/User")
sys.path.append(root + "/modules/Article")

# IMPORTS MODULES
module = __import__("HelloWorld")
my_class = getattr(module, "HelloWorld")

# This is our application object. It could have any name,
# except when using mod_wsgi where it must be "application"
def application(environ, start_response):

    results = []

    helloWorld = my_class()
    results.append(helloWorld.sayHello())

    output = "<br/>".join(results)

    print output

    ...

如您所见,我仍然需要这些行才能加载模块,

sys.path.append(root + "/modules")
sys.path.append(root + "/modules/User")
sys.path.append(root + "/modules/Article")

如果我有大量的文件夹和子文件夹怎么办?我要把它们都列出来吗?它最终会进入一个长长的列表,不是吗?

此外,使用 __import__ 似乎与此没有太大区别,

import os
import sys

root = os.path.dirname(__file__)
sys.path.append(root + "/modules")
sys.path.append(root + "/modules/User")
sys.path.append(root + "/modules/Article")

# IMPORTS MODULES
import hello
import HelloWorld

from HelloWorld import HelloWorld

# This is our application object. It could have any name,
# except when using mod_wsgi where it must be "application"
def application(environ, start_response):

我觉得后者更好看、更整洁。

有什么想法吗?

TL;DR:忘记它并使用显式导入。

更长的答案:

Python 不是 PHP - 既不是技术观点,也不是设计/哲学观点。

Python 的部分哲学(又名“Python's Zen”)是 "explicit is better than implicit"、"Readability counts" 和 "In the face of ambiguity, refuse the temptation to guess" - 这使得 "feature" 像 PHP 的 "autoload" 非常不符合 Python 标准,因为 1. 它比 "import mymodule" 或 "from mymodule import SomeName" 更不明确,2. 它的可读性也更差(你不'清楚地知道一个名称是从哪里导入的),以及 3. 当两个或多个模块定义相同的名称时(这在 Python 中是完全有效且很常见的),它必须尝试猜测你是哪个想要(这在技术上是不可能的)。

从技术角度来看,您无法在 Python 中以可靠的方式实现这样的功能 - 参见上面的第 3 点。虽然 PHP 的 require 语句和 Python 的 import 语句可能看起来相似,但它们实际上以完全不同的方式工作,并且 "execution models" 也是完全不同。

以 PHP 的方式自动重新加载源代码在 Python 中不实用。我建议你去读一读:

如果您真的必须拥有某些东西,请参阅其中描述的可与 mod_wsgi 一起使用的自动代码重新加载器的详细信息。不过永远不要在生产系统上使用它。

如果您正在进行开发,坦率地说,使用 mod_wsgi-express 可能会更好。参见:

mod_wsgi-express 的其中一个功能是 --reload-on-changes 选项,它可以为您实现自动代码重新加载。