Python:在函数上传递参数

Python:在函数上传递参数,python,Python,Python专家 我一直在尝试使用Python实现BST,下面是我的insert函数代码: 草案1: def insert(self, val): newNode = self._Node(val) if (self._root is None): self._root = newNode else: self._insert(self._root,val) def _insert(self, node, val): if n

Python专家

我一直在尝试使用Python实现BST,下面是我的insert函数代码:

草案1:

def insert(self, val):
    newNode = self._Node(val)

    if (self._root is None):
        self._root = newNode
    else:
        self._insert(self._root,val)

def _insert(self, node, val):

    if node is None:
        node = self._Node(val)

    elif val >= node._val:

        self._insert(node._right, val)
    else:
        self._insert(node._left, val)
def insert(self, val):
    newNode = self._Node(val)

    if (self._root is None):
        self._root = newNode
    else:
        self._insert(self._root,val)

def _insert(self, node, val):

    if val >= node._val:
        if node._right is None:
                node._right = self._Node(val)
        else:
                self._insert(node._right, val)
    else:
        if node._left is None:
                node._left = self._Node(val)
        else:
                self._insert(node._left, val)
但是,除了根,我无法构建树。我猜我把通过这两个函数的参数搞砸了,因为当我修改下面的代码时,我得到了正确的结果:

草案2:

def insert(self, val):
    newNode = self._Node(val)

    if (self._root is None):
        self._root = newNode
    else:
        self._insert(self._root,val)

def _insert(self, node, val):

    if node is None:
        node = self._Node(val)

    elif val >= node._val:

        self._insert(node._right, val)
    else:
        self._insert(node._left, val)
def insert(self, val):
    newNode = self._Node(val)

    if (self._root is None):
        self._root = newNode
    else:
        self._insert(self._root,val)

def _insert(self, node, val):

    if val >= node._val:
        if node._right is None:
                node._right = self._Node(val)
        else:
                self._insert(node._right, val)
    else:
        if node._left is None:
                node._left = self._Node(val)
        else:
                self._insert(node._left, val)

我正在努力理解为什么草案2有效,而草案1无效。有人帮忙吗?提前谢谢

您的基本误解是变量赋值如何工作以及如何与Python的求值策略交互:

基本上,在初稿中,当您执行以下操作时:

def _insert(self, node, val):

    if node is None:
        node = self._Node(val)
    ...
您只需将
self.\u节点(val)
的值分配给名称(变量)
node
,但当您离开作用域时,新对象将被销毁!即使
节点
用于引用方法调用传入的值,简单赋值也不会改变名称引用的对象,而是重新分配名称

然而,在你的第二稿中:

def _insert(self, node, val):

    if val >= node._val:
        if node._right is None:
            node._right = self._Node(val)
        else:
            self._insert(node._right, val)
您正在变异一个对象,即:`node.\u right=self.\u node(val)

下面是一个简单的例子,希望能有所启发:

>>> def only_assign(object):
...   x = 3
...   object = x
... 
>>> def mutate(object):
...   object.attribute = 3
... 
>>> class A:
...   pass
... 
>>> a = A()
>>> a
<__main__.A object at 0x7f54c3e256a0>
>>> only_assign(a)
>>> a
<__main__.A object at 0x7f54c3e256a0>
>>> mutate(a)
>>> a.attribute
3
>>仅定义\u分配(对象):
...   x=3
...   对象=x
... 
>>>def mutate(对象):
...   object.attribute=3
... 
>>>A类:
...   通过
... 
>>>a=a()
>>>a
>>>仅分配(a)
>>>a
>>>变异(a)
>>>a.属性
3.

我认为这是因为这样做:

node = self._Node(val) 
在_insert函数中,您不会更改左/右节点的值,而是将名称节点绑定到一个新的_节点对象,从而使左/右节点变为无

在第二稿中,您实际上是在左/右节点上影响一个新对象

下面是一个简单的例子来说明代码中发生了什么

猜猜打印(测试)将显示什么

test = [5, 5, 5]

def function(list):
   list[0] = 10
   list = range(1, 3)

function(test)
print test

如果你认为它会显示[1,2],那你就错了。。它实际上会显示[10,5,5],因为当执行list=range(1,3)时,我们将名称列表绑定到另一个对象,而不更改它绑定到的第一个对象(一个测试实际上绑定到该对象)

这些草稿之间的缩进差异正常吗?我可能在复制时弄乱了缩进。现在更新了意向书!:)非常感谢你!那么,这是否意味着调用函数中的任何赋值都不会改变对象,但对数据成员(对于类)的更改会改变对象?@GowthamGanesh是的。根据定义,分配给数据成员是该对象的一种变异。只要对对象的引用存在于某个地方,该更改就会反映在对象中。如果在函数离开作用域后没有对对象的引用存在,则该对象将被垃圾收集。