Использование self.xxxx в качестве параметра по умолчанию - Python - PullRequest
50 голосов
/ 05 апреля 2011

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

tree = Tree()
#insert a bunch of items into tree

затем я использую свою функцию makeList (), чтобы взять все узлы из дерева и поместить их в список. Для вызова функции makeList() я делаю tree.makeList(tree.root). Мне это кажется немного повторяющимся. Я уже вызываю объект дерева с помощью tree., поэтому tree.root - это просто пустая трата текста.

Прямо сейчас функция makeList:

    def makeList(self, aNode):
        if aNode is None:
            return []
        return [aNode.data] + self.makeList(aNode.lChild) + self.makeList(aNode.rChild)

Я хотел бы сделать входной параметр aNode параметром по умолчанию, таким как aNode = self.root (который не работает), чтобы я мог запустить функцию с этим, tree.makeList().

Первый вопрос: почему это не работает?
Второй вопрос: есть ли способ, которым это может работать? Как видите, функция makeList() является рекурсивной, поэтому я не могу ничего определить в начале функции или получаю бесконечный цикл.

EDIT Вот весь код в соответствии с просьбой:

class Node(object):
    def __init__(self, data):
        self.data = data
        self.lChild = None
        self.rChild = None

class Tree(object):
    def __init__(self):
        self.root = None

    def __str__(self):
        current = self.root

    def isEmpty(self):
        if self.root == None:
            return True
        else:
            return False

    def insert (self, item):
        newNode = Node (item)
        current = self.root
        parent = self.root

        if self.root == None:
            self.root = newNode
        else:
            while current != None:
                parent = current
                if item < current.data:
                    current = current.lChild
                else:
                    current = current.rChild

            if item < parent.data:
                parent.lChild = newNode
            else:
                parent.rChild = newNode

    def inOrder(self, aNode):
        if aNode != None:
            self.inOrder(aNode.lChild)
            print aNode.data
            self.inOrder(aNode.rChild)

    def makeList(self, aNode):
        if aNode is None:
            return []
        return [aNode.data] + self.makeList(aNode.lChild) + self.makeList(aNode.rChild)


    def isSimilar(self, n, m):
        nList = self.makeList(n.root)
        mList = self.makeList(m.root) 
        print mList == nList 

Ответы [ 3 ]

43 голосов
/ 06 апреля 2011

larsmans ответил ваш первый вопрос

На ваш второй вопрос, можете ли вы просто посмотреть, прежде чем прыгнуть, чтобы избежать рекурсии?

def makeList(self, aNode=None):
    if aNode is None:
        aNode = self.root
    treeaslist = [aNode.data]
    if aNode.lChild:
        treeaslist.extend(self.makeList(aNode.lChild))
    if aNode.rChild:
        treeaslist.extend(self.makeList(aNode.rChild))
    return treeaslist
33 голосов
/ 05 апреля 2011

Это не работает, потому что аргументы по умолчанию оцениваются во время определения функции, а не во время вызова:

def f(lst = []):
    lst.append(1)
    return lst

print(f()) # prints [1]
print(f()) # prints [1, 1]

Общая стратегия заключается в использовании параметра None по умолчанию.Если None является допустимым значением, используйте одноэлементный страж:

NOTHING = object()

def f(arg = NOTHING):
    if arg is NOTHING:
        # no argument
    # etc.
0 голосов
/ 12 марта 2019

Если вы хотите трактовать None как допустимый аргумент, вы можете использовать параметр **kwarg.

def function(arg1, arg2, **kwargs):
    try:
        arg3 = kwargs['arg3']
    except KeyError:
        arg3 = default

    # Continue with function

function("amazing", "fantastic") # uses default
function("foo", "bar", arg3=None) # Not default, but None
function("hello", "world", arg3="!!!")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...