【问题标题】:Python immutable function parameter [duplicate]Python不可变函数参数[重复]
【发布时间】:2014-10-13 16:50:45
【问题描述】:

我正在尝试理解 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类是不可变的吗?

【问题讨论】:

    标签: python object variable-assignment


    【解决方案1】:

    Python 类当然不是一成不变的。您可以随意更改它们(有些极端情况涉及扩展类型或 slots)。

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

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

    如果你想要这样(你不应该这样,但这是关于避免全局变量的不同讨论),你必须在 print_list 中声明 root 是全局的

    def print_list():
        global root
        ...
    

    然后你就不需要这个参数了。

    再次:不要这样做!!!

    如果您使用 pylint 之类的工具来检查您的代码,它应该会警告您参数名称“root”会影响模块全局名称“root”。

    【讨论】:

    • 非常感谢您的描述性回答。
    【解决方案2】:

    很简单:

    obj.do_something()
    

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

    obj = something_other
    

    放弃对旧对象的引用并使用另一个对象。

    对象的更改(当然)对对象的“其他”用户可见,而重新分配只会影响重新定义的位置。

    【讨论】:

    • 非常感谢您的贡献
    猜你喜欢
    • 2012-03-07
    • 2011-04-01
    • 2017-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-19
    • 2023-01-24
    • 1970-01-01
    相关资源
    最近更新 更多