使用self.xxxx作为默认参数 - Python

93 投票
3 回答
49938 浏览
提问于 2025-04-16 15:08

我正在尝试简化我的一个作业问题,并让代码变得更好。我正在处理的是一个二叉搜索树。目前,我在我的 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() 函数是递归的,所以我不能在函数开始时定义任何东西,否则会导致无限循环。

编辑
这是所有的代码,按照要求提供:

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 个回答

2

如果你想把 None 当作一个有效的参数来使用,可以用 **kwarg 这个参数。

def function(arg1, arg2, **kwargs):
    kwargs.setdefault('arg3', default)
    arg3 = kwargs['arg3']
    
    # Continue with function

function("amazing", "fantastic") # uses default
function("foo", "bar", arg3=None) # Not default, but None
function("hello", "world", arg3="!!!")

我还见过用 ... 或其他一些单例来这样使用。

def function(arg1, arg2=...):
    if arg2 is ...:
        arg2 = default
63

这个问题出现的原因是默认参数是在定义函数的时候就被计算出来了,而不是在调用函数的时候。

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.
67

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

撰写回答