2010-05-20 7 views
7

Hay varias utilidades - todos con diferentes procedimientos, limitaciones y sistemas operativos de destino - para conseguir un paquete de Python y todas sus dependencias y convertirlos en un solo programa binario que es fácil de enviar a los clientes:¿Incluye una aplicación de Python como un único archivo para admitir complementos o extensiones?

Mi situación va un paso más allá: los desarrolladores de terceros querrán escribir complementos, extensiones o complementos para mi aplicación. Por supuesto, es una pregunta desalentadora cómo los usuarios en plataformas como Windows podrían instalar complementos o complementos de manera más sencilla, de modo que mi aplicación pueda descubrir fácilmente que se han instalado. Pero más allá de esa pregunta básica hay otra: cómo un desarrollador de terceros puede agrupar su extensión con las bibliotecas que necesita la extensión (que pueden ser módulos binarios, como lxml) de modo que las dependencias del complemento estén disponibles para su importación al mismo tiempo que el complemento está disponible.

¿Cómo se puede abordar esto? ¿Necesitará mi aplicación su propia área de plug-in en el disco y su propio registro de complementos para que esto sea manejable? ¿O hay mecanismos generales, que podría evitar escribir yo mismo, que permitan que una aplicación que se distribuye como un ejecutable único mire a su alrededor y encuentre complementos que también se instalen como archivos únicos?

Respuesta

7

Debería poder tener un directorio de complementos que su aplicación escanea en tiempo de ejecución (o posterior) para importar el código en cuestión. Aquí hay un ejemplo que debería funcionar con el código .py o .pyc regular que incluso funciona con complementos almacenados dentro de archivos zip (para que los usuarios simplemente puedan soltar algunosplugin.zip en el directorio 'plugins' y hacer que funcione mágicamente):

Digamos que tengo un complemento llamado "foo.py" en un directorio llamado 'plugins' (que está en el directorio base de mi aplicación) que agregará una nueva capacidad a mi aplicación. El contenido puede tener este aspecto:

from plugin_stuff import Plugin 

class Foo(Plugin): 
    """An example plugin.""" 
    self.menu_entry = {'Tools': {'Foo': self.bar}} 
    def bar(self): 
     return "foo plugin!" 

pude inicializar mis plugins cuando inicio mi aplicación, así:

plugin_dir = "%s/plugins" % os.getcwd() 
plugin_list = get_plugins(plugin_dir) 
init_plugin_system({'plugin_path': plugin_dir, 'plugins': plugin_list}) 
plugins = find_plugins() 
plugin_menu_entries = [] 
for plugin in plugins: 
    print "Enabling plugin: %s" % plugin.__name__ 
    plugin_menu_entries.append(plugin.menu_entry)) 
add_menu_entries(plugin_menu_entries) # This is an imaginary function 

que debería funcionar siempre y cuando el complemento es o bien un .py o .pyc archivo (suponiendo que es compilado en byte para la plataforma en cuestión). Puede ser un archivo independiente o dentro de un directorio con un init .py o dentro de un archivo zip con las mismas reglas.

¿Cómo sé que esto funciona? Es cómo implementé complementos en PyCI. PyCI es una aplicación web, pero no hay ninguna razón por la cual este método no funcione para una GUI normal. Para el ejemplo anterior, elegí usar una función imaginaria add_menu_entries() junto con una variable de objeto Plugin que podría usarse para agregar los métodos de un complemento a los menús de tu GUI.

Esperamos que esta respuesta lo ayude a crear su propio sistema de complementos. Si quiere ver exactamente cómo se implementa, le recomiendo que descargue el código fuente de PyCI y consulte plugin_utils.py y el complemento de ejemplo en el directorio plugins_enabled.

+0

¡Gracias por señalar el enfoque de PyCl! ¿Qué hacen sus autores de complementos cuando quieren agrupar dependencias, como la biblioteca "lxml" que mencionó mi pregunta? ¿Qué pasa si dos complementos necesitan "lxml" pero cada paquete tiene una versión ligeramente diferente? ¿Y qué pasa si "lxml" tiene partes binarias que generarán una DLL en Windows pero un .so en Linux? –

+0

Los autores de complementos pueden incluir las dependencias que necesiten en la ruta base de su complemento. Esto funciona porque la ruta del complemento se agrega a sys.path justo antes de que se importe. La única advertencia sería que si un complemento requiere una dependencia específica de la plataforma, el autor del complemento debería tener un paquete para cada arquitectura que esté dispuesto a admitir. También me gustaría mencionar que PyCI incluye métodos (en Plugin()) para recuperar archivos desde el directorio del plugin. Por lo tanto, si un complemento hace uso de contenido estático, puede publicarse incluso si el complemento está en un archivo zip. –

0

Aquí hay otro ejemplo de una aplicación de Python que utiliza complementos: OpenSTV. Aquí, los complementos solo pueden ser módulos de Python.

Cuestiones relacionadas