Python 中对象之间的相互递归

Mutual recursion between objects in Python

我目前正在开发一个模块,该模块允许用户通过创建任务对象的实例来构建任意任务网络模型(用于离散事件模拟)(我的模块提供了一个任务 class) .除其他外,任务包含描述其完成效果的逻辑,例如不同任务的启动。这样,任务class的一个实例可能会引用一个或多个其他实例,具有循环references/mutual递归的可能性。

这是我的代码的一个极其简化的版本:

TaskModule.py

class Task(object):
    def __init__(self, name, effect):
        self.name = name
        self.effect = effect

def execute(task):
    task.effect()

TaskTest.py

task1 = task("Do the first thing", execute(task2))
task2 = task("Do the second thing", execute(task3))
task3 = task("Do the third thing", execute(task1))

此实现的问题是我在定义 task2 和 task3 之前引用它们。如果我可以排除循环引用,那不会是世界末日——这只是一个重新排列对象实例化顺序的问题——但我相信我应该适应这种可能性。我已经考虑了几个潜在的解决方法——大多数会涉及要求用户间接引用任务(即通过一些唯一的标识符值)——但我想知道是否有更优雅的解决方案涉及一种巧妙的抽象形式。

确保实例化 tasks/generating 任务网络(如 TaskTest.py 中所示)的过程尽可能简单易行是该项目的首要任务,因为这是用户的首要任务我模块的大部分时间都花在了上面。

我尝试搜索,但似乎大多数关于相互 recursion/cyclical 引用主题的问题都涉及函数或 classes 而不是实例。

您需要某种占位符对象来表示其依赖关系未知的任务。那么你可以做

task1 = Task("Do the first thing", [Placeholder()])
task2 = Task("Do the second thing", [execute(task1)])
task3 = Task("Do the third thing", [execute(task2)])
task1.add_dependency(task3)
task1.remove_placeholders()

它需要是 Task("...", [Placeholder()]) 而不是 Task("...", []) 因为后者代表一个 没有 依赖关系的任务,你也希望能够快递。

所以,我认为这里的问题是名称和对象被混淆了。我可能会使用一种结构,其中任务对象组织在字典中,字符串或枚举用作键。这样您就可以在 names 分配之前参考它们。

class TaskManager:
    def __init__(self, tasks=None):
        self.tasks = tasks or {}

    def register(self, name, task):
        self.tasks[name] = task

    def execute(self, name):
        self.tasks[name].effect()

实现此目的的一种方法是创建一个 TaskList 对象来管理任务。实现由您决定,但本质上您希望有一个按顺序执行的任务列表。如果某个任务产生了进一步的工作(即,非 None return),则此结果任务将附加到列表中。

显然,这很容易产生一个无限的过程,因此您可能需要考虑如何处理它,但这更多地涉及 UI 设计。