2

我正在用 python 编写一个应用程序,它将用 py2exe 导出到一个可执行文件。我正在尝试编写一个插件系统,该系统在应用程序是 exe 时可以工作。

我的原始代码看起来像

import os
Plugins=os.listdir('plugins')
for P in Plugins:
    PItems=os.path.splitext(P)
    PName=PItems[0]
    if PItems[len(PItems)-1]=='.py':
        Mod=__import__('plugins.'+PName,fromlist=['*'])
        Mod.init()

但是当导出到 exe 时,它​​在尝试导入时找不到模块“plugins.(pluginName)”。

插件还应该能够导入 my_application 以访问应用程序 api。

mcEdit(用python编写)和Sublime Text(不确定)可以做到这一点,但尽管搜索了源代码,但我找不到如何做到的。

如何编写导出到 exe 时可以使用的东西?

编辑: 澄清

  • 插件应在应用程序加载时自动加载。它们存储在plugins/目录中
  • 插件应该能够与应用程序交互,import myapplication然后运行 ​​api 调用,例如myapplication.getFoo()myapplication.setBar(Bar)
  • 这些插件可以运行一次,也可以在鼠标单击或移动之类的事件上运行,甚至可以在每次绘制屏幕时运行。我希望他们在应用程序运行时保持其状态(变量值、对象等)。
4

1 回答 1

0

好的。我想我有一个答案。

文件结构如下:

api/
  - __init__.py
  - etc...
plugins/
  - plugin.py
  - etc...
- MainScript.py
- PyExeCreator.py

MainScript.py 看起来像:

import os,sys, api

RootDir=os.getcwd() 
#Add this directory to export
if RootDir not in sys.path:
    sys.path.append(RootDir)

#Plugin stuff
def LoadPlugins():
    PluginsDir=os.path.join(RootDir,'plugins')
    Plugins=os.listdir(PluginsDir)

    Modules=[]
    for P in Plugins:
        PItems=os.path.splitext(P)
        PName=PItems[0]
        if PName!='__init__' and PItems[len(PItems)-1]=='.py':
            print "Loading plugins."+PName
            Mod=__import__("plugins."+PName,fromlist=['*'])
            Modules.append(Mod)
    return Modules
def RunPlugins(Modules):
    for Plugin in Modules:
        Plugin.Run()

Plugins=LoadPlugins()

#Just checking plugins can modify variables.
api.Run()
RunPlugins(Plugins)
api.Run()

api/__init__.py 看起来像:

MOTD="HI"
def Run():
    global MOTD
    print "API MOTD: "+MOTD

可能会是一个更令人兴奋的 API。插件/plugin.py

import api
def Run():
    api.MOTD="HELLO WORLD!"
    print "This is a plugin running!"

重要的是编译器 PyExeCreator.py

from distutils.core import setup
import py2exe

setup(
    name='Tester',
    console=['Loader.py'],
    packages=['api']
)

我缺少的关键位是在packagesfor中包含 APIdistutils并为当前目录设置搜索目录 ( sys.path.append(os.getcwd()))

于 2013-08-01T08:11:56.073 回答