Python为什么我不能将属性作为类内另一个方法的参数传递?

2024-07-02 14:37:37 发布

您现在位置:Python中文网/ 问答频道 /正文

class Node:
    """A Tree Node with 3 attributes: l_child, r_child and data"""
    def __init__(self, val):
        self.data = val
        self.l_child = None
        self.r_child = None

class BST(object):
    """Implement a Binary Search Tree class"""
    def __init__(self):
        self.root = None
        print "Initial root", self.root

    def insertRecur(self, node, data):
        if node is None:
            node = Node(data)
        else:   
            if data < node.data:
                insertRecur(node.l_child, data)
            if data > node.data:
                insertRecur(node.r_child, data)

    def Insert(self, data):
        self.insertRecur(self.root, data)

抱歉,伙计们 这就是我原来的代码。我想用Python实现一个二叉搜索树类。我想这样做

test = BST()
test.Insert(1)
print test.root

以及测试根是None


Tags: testselfnonenodechildtreedataif
3条回答

只需将self.data的值赋给node,而不是variable self.data本身。您在Insert函数中调用的正是:

self.Recur(None, 5)

我猜你想要的是:

self.Recur(*self.data, 5)

但是python中没有pointer。您可以将Recur的代码合并到Insert,或者如果您想同时维护RecurInsert

    def Recur(self, node, data):
        if node is None:
            node = data
        return node

    def Insert(self, data):
        self.data = self.Recur(self.data, data)

当然还是None。你没有给它赋值。应该是。你知道吗

def Insert(self, data):
    self.data = data
    self.Recur(self.data, data)

但是,函数

def Recur(self, node, data):
    if node is None:
        node = data

因为node没有在任何地方使用,只分配给。你知道吗

编辑:在更新代码之后,我们可以看到您正在尝试做什么。你的test.root之所以是None,是因为你从不分配它。问题在于:

def insertRecur(self, node, data):
    if node is None:
        node = Node(data)

self.insertRecur(self.root, data)调用此函数时,它指向与self.root相同的值,即None。当您执行node = Node(data)操作时,您正在重新指派node以指向Note(data),这不会重新指派self.root。请改为:

class Node:
    """A Tree Node with 3 attributes: l_child, r_child and data"""
    def __init__(self):
        self.data = None
        self.l_child = None
        self.r_child = None

class BST(object):
    """Implement a Binary Search Tree class"""
    def __init__(self):
        self.root = Node()
        print "Initial root", self.root

    def insertRecur(self, node, data):
        if node.data is None:
            node.data = data
        elif data < node.data:
            node.l_child = node.l_child or Node()
            self.insertRecur(node.l_child, data)
        else:
            node.r_child = node.r_child or Node()
            self.insertRecur(node.r_child, data)

    def Insert(self, data):
        self.insertRecur(self.root, data)

您的示例将在某些编程语言中工作。(例如 C允许通过指针引用实现这一点。)它在这里不起作用的原因是Python中如何定义方法调用的语义。你知道吗

Python中的名称绑定

当你写作的时候

self.data = None

这将为对象None分配一个新名称(self.data)。你知道吗

其中self.Recur定义为

def Recur(self, node, data):
    if node is None:
        node = data

下面在Recur方法的上下文中为None提供了一个新名称: node。你知道吗

self.Recur(self.data, data)

但是,同一对象的内部作用域中的这个新名称(node)与外部作用域中的另一个名称(self.data)没有关联。你知道吗

当你写作的时候

node = data

这会将名称node分配给一个新值,即 名称data引用。同样,这不影响名称 self.data。有关更多信息,请查看此blog post。你知道吗

如何做你想做的

另一方面,如果希望Recur能够将值赋给test对象的任何属性,则可以这样做。在这里 是实现它的一种方法:

class test:
    def __init__(self):
        self.data = None

    def Recur(self, nodeName, data):
        if self[nodeName] is None:
            self[nodeName] = data;

    def Insert(self, data):
        self.Recur("data", data) 

    __getitem__ = self.__getattr__
    __setitem__ = self.__setattr__

NB:此代码未经测试

这允许Insert选择"data"为其赋值的名称("data")。Recur则使用Python的dict key get item语法为准dict对象中的键data赋值;但是,我们将get item和set item语义设置为与get属性相同,并将属性语义设置为与最后两行相同-这确保了self["name"]self.name的意思相同。一个不那么神秘的实现是:

def __getitem__(self, key):
    return self.__getattr__(key)

相关问题 更多 >