【问题标题】:Python as an end user script in a python appPython 作为 Python 应用程序中的最终用户脚本
【发布时间】:2010-06-11 17:52:38
【问题描述】:

我有一个用 python 编写的应用程序。我想让我的用户能够通过允许他们运行自己的脚本来操作应用程序对象。他们很可能在脚本中出错。如果出现错误,我想确保应用程序不会停止运行。我想在我的应用中嵌入一个调试器来帮助他们调试脚本。

例如我在 shape.py 中的应用中定义了一个点类:

class QVPoint(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y
    def addPoint(self, aPoint):
        self.x = self.x + aPoint.x
        self.y = self.y + aPoint.y

我想让他们运行如下脚本:

from shapes import QVPoint
a = QVPoint(1,1)
a.addPoint(QVPoint(2,2))
print "<" + str(a.x) + ',' + str(a.y) + ">"
print "<%d,%d>" % (a.x, a.y)
print 'done'

我认为这必须使用解释器、调试器,但我不确定有两个方面,1)如何将在应用程序中创建的对象公开给脚本,以及 2)如何确保应用程序不如果错误导致脚本停止,则停止。

我确定之前一定有人问过这个问题,但我找不到。欢迎所有答案。

谢谢

大卫

【问题讨论】:

  • 请格式化您的代码。
  • 只是为了澄清我想与脚本共享应用程序的状态。子流程将涉及设计一个协议来传达应用程序状态更改,并且会非常慢。在单独的线程上唯一可能需要的是调试器——尽管我可能能够使用远程调试器。
  • 我认为我的解决方案是使用 try:except 包裹的 compile() 和 eval()。使用名为沙盒的空白模块的全局变量。

标签: python extensibility


【解决方案1】:

我建议您使用单独的解释器实例(单独的 python 进程)来评估用户的脚本。这将保证用户脚本中的任何中断都不会影响您的应用程序。您可以使用 os 模块运行外部进程,这是一种方法:http://docs.python.org/library/os.html#os.popen

您可以允许用户的脚本从您的应用程序中导入某些模块,以便脚本可以访问您定义的变量。

【讨论】:

  • 请注意,建议使用subprocess 而非os 来启动外部进程。
  • 不错,很抱歉,子进程是更好的选择。
【解决方案2】:

需要做出一些决定。

  1. 你想在你的应用程序的同一个进程中运行它还是在一个单独的进程中运行它?

    在不了解您的应用的很多细节的情况下,我倾向于在单独的进程中运行它们。为此使用subprocess 模块。您可以创建一个应用程序启动器,然后调用您的用户脚本。如果它抛出异常,您可以捕获它并格式化结果并报告给用户。

  2. 您想向您的用户公开类还是向您的用户公开对象?

    在您的示例中,似乎共享课程就足够了。这应该相当简单。

    如果只是类,您可以简单地将其包含在 PYTHONPATH 中。然后您的用户可以导入它们。如果您想公开一个对象,可能需要您在此过程中执行此操作。否则,您必须找到一种方法来序列化您的对象并将其传输到新进程。

【讨论】:

  • 澄清一下,我希望共享对象和类。如果我使用子进程,那么我将需要创建代理和存根以在两个进程之间进行通信——这似乎比需要的工作更多。这也意味着任何想要扩展应用程序的人都需要编写代理和存根,这绝对是不可取的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-29
  • 1970-01-01
  • 1970-01-01
  • 2016-08-03
  • 2017-05-24
  • 2019-04-13
相关资源
最近更新 更多