如何在Python中干净地修改参数?

时间:2015-12-03 02:23:13

标签: python function

我有以下代码用于修改递归传递给函数的节点(节点包装在一个数组中,以便在函数返回后修改是持久的):

是否有更好或更清晰的方法来修改参数?

`

class node(object):
    def __init__(self, value, next=None):
        self._value = value
        self._next = next

    def __repr__(self):
        return "node({0})".format(self._value)


    @property
    def next(self):
        return self._next



def foo(a, b):
    if b == 0:
        print "setting to next node",
        a[0] = a[0].next
        print a
        return

    print a
    foo(a, b-1)
    print a

n = node(5, node(8))
foo([n], 2)

`

问题的回答是:How do I pass a variable by reference?

2 个答案:

答案 0 :(得分:0)

因为您正在操作的参数是对象。您可以使用__dict__来更改对象的整个属性。它相当于改变项目的每个属性。您可以尝试以下代码:

class node(object):
    def __init__(self, value, next=None):
        self._value = value
        self._next = next

    def __repr__(self):
        return "node({0})".format(self._value)


    @property
    def next(self):
        return self._next



def foo(a):
    print "setting to next node\n",
    a.__dict__ = getattr(a.next, '__dict__', None)
    return

n = node(5, node(8, node(7)))

print n._value, '->' ,n._next._value
foo(n)
print n._value, '->' ,n._next._value

希望这可以帮到你。

答案 1 :(得分:0)

要修改某些东西,那东西必须是可变的。您的node个实例是可变的:

n = node(3)
assert n.value == 3
n.value = 5
assert n.value == 5  # it was modified!

此外,您的函数无法返回任何值。在你的情况下,这可能是一个错误的方法。另外,我坦率地不明白为什么要使用引用0值的数字(n - 1.next)。这些必须是节点实例,而不是数字。

显然,您正在制作链接列表实现,而您的foo函数会尝试通过遍历列表来删除第n个节点。 (请注意以描述性方式命名您的功能;它可以帮助您和回答您问题的人。)

我是怎么做到的:

class Node(object):  # class names are usually TitleCase
    def __init__(self, value, next=None):
        self.value = value
        self.next = next  # no properties for simplicity

    def __repr__(self):
        return "node({0})".format(self.value)


def asList(node):  # nice for printing
    if not node:
        return []
    return [node.value] + asList(node.next)


def removeNodeAt(head_node, index):
  """Removes a node from a list. Returns the (new) head node of the list."""
  if index == 0:  # changing head
    return head_node.next
  i = 1  # we have handled the index == 0 above 
  scan_node = head_node
  while i < index and scan_node.next:
    scan_node = scan_node.next
    i += 1
  # here scan_node.next is the node we want removed, or None
  if scan_node.next:
    scan_node.next = scan_node.next.next  # jump over the removed node
  return head_node

有效:

>>> n3 = Node(0, Node(1, Node(2)))
>>> asList(removeNodeAt(n3, 2))
[0, 1]

>>> n3 = Node(0, Node(1, Node(2)))
>>> asList(removeNodeAt(n3, 1))
[0, 2]