所以我有一个目录树,如下所示:
pluginlist.py
plugins/
__init__.py
plugin1.py
plugin2.py
...
并希望从plugin1,plugin2等中连接一个类似命名的字典。
我这样做的方式如下(来自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 Server)上运行它会产生一个空字典。
答案 0 :(得分: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
设置为某个非空列表。
答案 1 :(得分:0)
您的源代码是否具有Windows CRLF行结尾?尝试添加print repr(firstline)
以检查其是否以\r\n
而不是\n
结尾。
答案 2 :(得分: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)
答案 3 :(得分:0)
想出我的问题!
os.path.isfile(file)
测试无效,因为Linux需要插件文件的绝对路径。所以用
替换所有文件实例os.path.join(os.getcwd(), file)
似乎可以解决所有问题。