Python不可变函数参数

时间:2014-08-20 10:53:58

标签: python object variable-assignment

我试图了解Python的核心思想,并且我遇到了一篇很好的文章,解释了将参数引用传递给对象。例如;

def add_to_list(list_to_add, value):
  list_to_add.append(value)

能够更改原始list_to_add参数;

def change_list(list_to_add):
  list_to_add = [1, 2, 3, 5]

赢了做了什么。

我目前正在编写一个基本的链表打印功能,就像它一样;

class Node:
  def __init__(self, val, next=None):
    self.val = val
    self.next = next

root = Node(2, Node(3, Node(4, Node(5, Node(6)))))

def print_list(root):
  while root:
    print root.val,
    root = root.next
  print ''

你猜对了。它并没有改变根的价值。现在我的问题是这是怎么发生的。是因为python类是不可变的吗?

2 个答案:

答案 0 :(得分:4)

Python类当然不是不可变的。您可以随意更改它们(有些角落案例涉及扩展类型或广告位)。

但是,你在这里做的是定义一个模块级(全局)变量root,然后在print_list中定义一个参数名root。

调用print_list(root)然后将某些内容分配给root将 NOT 更改模块级全局!

如果你想要那个(你不应该想要那个,但这是关于避免全局变量的另一个讨论),你必须将print_list中的root声明为全局

def print_list():
    global root
    ...

然后你不需要参数。

AGAIN :不要这样做!

如果您使用像pylint这样的工具来检查您的代码,它应该已经警告您参数名称" root"阴影模块全局名称" root"。

答案 1 :(得分:1)

很简单:

obj.do_something()

对传递的对象进行操作,可能会修改它(例如list_to_add.append()),而

obj = something_other

丢弃对旧对象的引用并使用不同的引用。

对象的更改(当然)对于"其他"对象的用户,而重新分配仅影响重新定义的位置。