1

所以我有一个目录树如下:

pluginlist.py
plugins/
    __init__.py
    plugin1.py
    plugin2.py
    ...

并希望从每个插件 1、插件 2 等中连接一个名称相似的字典。

我这样做的方式如下(来自pluginlist.py):

import os

pluginFolderName = "plugins"
pluginFlag = "##&plugin&##"

commands = {}

os.chdir(os.path.abspath(pluginFolderName))

for file in os.listdir(os.getcwd()):
    if os.path.isfile(file) and os.path.splitext(file)[1] == ".py":
        fileo = open(file, 'r')
        firstline = fileo.readline()
        if firstline == "##&plugin&##\n":
            plugin_mod = __import__("plugins.%s" % os.path.splitext(file)[0])
            import_command = "plugin_commands = plugin_mod.%s" %     os.path.splitext(file)[0]
            exec import_command
            commands = dict(commands.items() + plugin_commands.commands.items())
print commands

(打印命令用于测试目的)

在 Windows 上运行它会给出正确的命令字典,但在 Linux(Ubuntu 服务器)上运行它会给出一个空字典。

4

4 回答 4

2

尝试:

for file in os.listdir(os.getcwd()):
    basename, ext = os.path.splitext(file)
    if os.path.isfile(file) and ext == ".py":
        with open(file, 'r') as fileo:
            firstline = fileo.readline()
            if firstline.startswith("##&plugin&##"):
                plugin_mod = __import__("plugins.%s" % basename, fromlist = [True])
                plugin_commands = getattr(plugin_mod, basename)
                commands.update(plugin_commands.commands)

当你打电话__import__('A.B')时,包裹A被退回。当您调用 时__import__('A.B', fromlist = [True]),将返回模块B。在我看来你想要B。因此,在 Windows 和 Linux 上,您都需要设置fromlist一些非空列表。

于 2012-04-04T02:54:02.637 回答
0

您的源代码是否有 Windows CRLF 行尾?尝试添加 aprint repr(firstline)以检查它不以\r\n而不是结尾\n

于 2012-04-04T02:58:46.773 回答
0

如果插件缺少标识符,我会在打印警告else:的语句上放置一个分支if

此外,您可能不关心行尾,因此firstline.strip()在检查时调用可能会解决您的问题

最后,迂腐地,你可以加入file路径pluginFolderName而不是使用os.chdir()

未测试:

pluginFolderName = "plugins"
pluginFlag = "##&plugin&##"

pluginFolderName = os.path.abspath(pluginFolderName)

commands = {}
for file in os.listdir(pluginFolderName):
    # Construct path to file (instead of relying on the cwd)
    file = os.path.join(pluginFolderName, file)

    if os.path.isfile(file) and os.path.splitext(file)[1] == ".py":
        fileo = open(file, 'r')
        firstline = fileo.readline()

        if firstline.strip() == pluginFlag:
            # Strip firstline to ignore trailing whitespace

            plugin_mod = __import__("plugins.%s" % os.path.splitext(file)[0])
            plugin_cmds = getattr(plugin_mod, os.path.splitext(file)[0])
            commands.update(plugin_cmds)
         else:
             print "Warning: %s is missing identifier %r, first line was %r" % (
                 file, PLUGIN_IDENTIFIER, firstline)
于 2012-04-04T03:24:30.943 回答
0

想通了我的问题!这

os.path.isfile(file)

测试不起作用,因为 Linux 想要插件文件的绝对路径。因此,将文件的所有实例替换为

os.path.join(os.getcwd(), file)

似乎可以解决所有问题。

于 2012-04-04T18:21:16.850 回答