基于类的“任务”模块的良好模式?

时间:2013-05-20 02:23:11

标签: python design-patterns plugins python-2.7 module

我正在尝试用Python(2.7)设计一个易于扩展/模块化的命令行应用程序。每个模块称为“任务”。每个文件都有一个任务,包含在tasks /目录中,每个任务包含一个Task的子类,以及一个包含给定任务的代码入口点的run()方法。因为我希望每个“任务文件”包含将任务注册到系统所需的所有内容。每个任务都包含元数据,例如帮助,可用参数,身份验证信息,类别等。这些不仅仅是静态属性 - 例如,帮助系统使用Template来替换帮助文本中的$variable

这是一些示例代码:

class TestTask(Task):
    description = "This task prints 'Hello world...' and exits."
    help = "Usage: $argv0 $task ...\n ..."

    def __init__(self, arguments=None):
        super(TestTask, self).__init__(description=self.description, arguments=arguments, help=self.help)

    def run(self):
        print("Hello world...")
那么,那么,我们如何显示任务的帮助?或者获取包含描述的所有任务的列表?好吧,我们必须有效地扫描目录,导入,加载和实例化每个任务,只需在其上调用getHelp()getDescription()。其中一些任务相当繁重。 “列出任务”的加载时间超过一秒,并且很明显。我想过缓存它,但看起来有点矫枉过正。

更清洁/更快的方法是什么?我应该以某种方式缓存任务元数据?我希望它尽可能地动态,以简化任务的开发。我想过一个包含元数据的内部类,但不确定。我相信所有任务的import仍然需要处理,而且我不清楚在“Meta”内部类和包含{{1}的内容之间共享信息的正确方法}。更新的python如此疑惑,如果我错过了什么。你们是如何设计你的插件模型的?谢谢!

1 个答案:

答案 0 :(得分:2)

我不确定我是否完全理解你的问题,但我认为这个说法

  

我们必须有效地扫描目录,导入,加载和实例化每个任务只是为了调用getHelp()

显然不是真的。例如,为了获得静态的编译时数据,类不需要实例化(重)实例。加载器非常快,特别是在使用预解析的.pyc文件时。

我正在考虑一个例子,但值得注意的是

 import Task
 import TestTask
 print(TestTask.description)

相对于

几乎是瞬间的
 tt = TestTask()
 print(tt.get_help())

因为前者不需要创建实例。

添加了示例

我使用包含112k源代码行的194个模块的python标准库作为导入速度测试。删节代码是:

import abc
import aifc
import anydbm
import argparse
import ast
…
import webbrowser
import whichdb
import xdrlib
import xmllib
import xmlrpclib
import zipfile
print(tty.setraw.__doc__)

在我的动力不足的笔记本电脑上运行230毫秒。 __doc__属性是函数docstring,它在导入时绑定到名称,即使从预解析的.pyc文件加载也是如此。