Композитный шаблон для приложения GTD

Это продолжение одного из моих предыдущих вопросов

Вот мои занятия.

#Project class     
class Project:
    def __init__(self, name, children=[]):
        self.name = name
        self.children = children
    #add object
    def add(self, object):
        self.children.append(object)
    #get list of all actions
    def actions(self):
        a = []
        for c in self.children:
            if isinstance(c, Action):
                a.append(c.name)
        return a
    #get specific action
    def action(self, name):
        for c in self.children:
            if isinstance(c, Action):
                if name == c.name:
                    return c
    #get list of all projects
    def projects(self):
        p = []
        for c in self.children:
            if isinstance(c, Project):
                p.append(c.name)
        return p
    #get specific project
    def project(self, name):
        for c in self.children:
            if isinstance(c, Project):
                if name == c.name:
                    return c

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

    def mark_done(self):
        self.done = True

Вот какая у меня проблема Если я создаю большой проект с несколькими небольшими проектами, я хочу посмотреть, что это за проекты или действия для текущего проекта, однако я получаю их все в дереве. Вот тестовый код, который я использую (обратите внимание, что я специально выбрал несколько разных способов добавления проектов и действий для тестирования, чтобы убедиться, что разные способы работают).

life = Project("life")

playguitar = Action("Play guitar")

life.add(Project("Get Married"))

wife = Project("Find wife")
wife.add(Action("Date"))
wife.add(Action("Propose"))
wife.add(Action("Plan wedding"))
life.project("Get Married").add(wife)

life.add(Project("Have kids"))
life.project("Have kids").add(Action("Bang wife"))
life.project("Have kids").add(Action("Get wife pregnant"))
life.project("Have kids").add(Project("Suffer through pregnancy"))
life.project("Have kids").project("Suffer through pregnancy").add(Action("Drink"))
life.project("Have kids").project("Suffer through pregnancy").add(playguitar)

life.add(Project("Retire"))
life.project("Retire").add(playguitar)

В жизни должно быть несколько проектов, в том числе несколько проектов. Структура примерно такая (где отступы - проекты, а - действия)

Life
    Get Married
        Find wife
            - Date
            - Propose
            - Plan wedding
    Have kids
        - Bang wife
        - Get wife pregnant
        Suffer through pregnancy
            - Drink
            - Play guitar
    Retire
        - Play guitar

Я обнаружил, что life.actions() возвращает каждое действие в дереве, когда оно не должно возвращать ни одного. life.projects() возвращает все проекты, даже подпроекты, когда мне нужны только "Жениться", "Иметь детей" и "Уйти на пенсию". Что я делаю не так?

1 ответ

Решение

Проблема с вашей инициализацией проектов:

 __init__(self, name, children=[]):

Вы получаете только один список, который используется всеми проектами, которые вы создаете, без передачи значения для детей. Смотрите здесь для объяснения. Вместо этого вы хотите сделать None по умолчанию и инициализировать пустой список всякий раз, когда значение None.

 __init__(self, name, children=None):
    if children is None:
       children = []
Другие вопросы по тегам