简单GTD应用程序的Python类

时间:2009-07-23 23:48:09

标签: python recursion gtd

我正在尝试为自己编写一个非常基本的GTD应用程序,不仅要有条理,还要更好地编写代码并在Python上做得更好。但是我对这些课有点麻烦。

以下是我到目前为止的课程:

class Project:
    def __init__(self, name, actions=[]):
        self.name = name
        self.actions = actions
    def add(self, action):
        self.actions.append(action)

class Action:
    def __init__(self, do='', context=''):
        self.do = do
        self.context = context

每个项目都有对它的操作,但是我想这样做,以便项目也可以包含其他项目。每天说我想打印出一切清单。我无法想出如何构建一个看起来像这样的列表

> Project A
>        Actions for Project A
>     Project B
>         Sub project A
>             Actions for Sub project A
>         Sub project B
>             Actions for Sub project B
>         Sub project C
>             Sub sub project A
>                 Actions for sub sub project A
>             Sub sub project B
>                 Actions for sub sub project B
>             Actions for Sub project C
>         Actions for Project B

我很清楚将使用递归。我正在努力创建另一个名为SubProject的类并将Project子类化为它。那里的东西只会让我的大脑异常。

我已经能够获取项目并将它们添加到Project类的actions属性中,然后我遇到了MegaProject.actions.action.actions.action情境开始弹出的地方。

如果有人可以帮助解决课程结构问题,我们将不胜感激!

3 个答案:

答案 0 :(得分:3)

您可以创建一个子项目成员,类似于您的操作列表,并以类似的方式为其分配项目。不需要对Project进行子类化。

class Project:
    def __init__(self, name, actions=[], subprojects=[]):
        self.name = name
        self.actions = actions
        self.subprojects = subprojects

    def add(self, action):
        self.actions.append(action)

    def add_project(self, project)
        self.subprojects.append(project)

更好的是,您可能希望实现复合模式,其中Projects是复合模式,而Actions是离开。

class Project:
    def __init__(self, name, children=[]):
        self.name = name
        self.children = children

    def add(self, object):
        self.children.append(object)

    def mark_done(self):
        for c in self.children:
            c.mark_done()

class Action:
    def __init__(self, do):
        self.do = do
        self.done = False

    def mark_done(self):
        self.done = True

它们的关键是项目与动作具有相同的接口(添加/删除方法除外)。这允许以递归方式调用整个树上的方法。如果你有一个复杂的嵌套结构,你可以在顶层调用一个方法,并将它过滤到底部。

如果您想要一个方法来获取树中所有叶节点的平面列表(Actions),您可以在Project类中实现这样的方法。

def get_action_list(self):
    actions = []
    for c in self.children:
        if c.__class__ == self.__class__:
            actions += c.get_action_list()
        else:
            actions.append(c)
    return actions

答案 1 :(得分:0)

我建议您查看可以应用于“Project”类的composite pattern。如果你正确地构建了你的结构,你应该能够将动作变成那棵树的叶子,就像你在你的例子中所描述的那样。

例如,你可以做一个Project类(抽象),一个ProjectComposite类(具体)和你的动作类作为叶子。

答案 2 :(得分:0)

您是否评估过现有的GTD工具?我会看一下现有GTD工具使用的文件格式,尤其是保存到XML的那些。这可以让您了解组织此类数据的方式往往有效。

结构范围从相当简单(TaskPaper)到巴洛克(OmniFocus)。环顾四周,了解别人在你面前的所作所为。