【问题标题】:Python: why does this local list variable in class method retain its value?Python:为什么类方法中的这个局部列表变量保留它的值?
【发布时间】:2017-05-15 15:03:15
【问题描述】:

我四处搜索并找到了this article,这让我了解了为什么会发生这种情况——看来我刚刚遇到了一个更复杂、更微妙的案例。但正是这些微妙之处让我感到困惑并寻找更清晰的解释。 (我怀疑这很重要,但以防万一:我在 Windows 7 上使用 Python 2.7.x。)

起点是这段代码,我从一个更大、更复杂的应用程序中提炼出我第一次遇到问题的地方。

class MyClass():
    def printStuff(self,myList=[1,2,3],myInt=4):
        print '--------------------------------'
        print 'myList at start: '+str(myList)
        print 'myInt  at start: '+str(myInt)
        doNotCare = myList.pop()
        myInt = myInt - 1
        print 'myList at end:   '+str(myList)
        print 'myInt  at end:   '+str(myInt)

testMC = MyClass()
testMC.printStuff()
testMC.printStuff()
testMC.printStuff()

...生成以下输出:

--------------------------------
myList at start: [1, 2, 3]
myInt  at start: 4
myList at end:   [1, 2]
myInt  at end:   3
--------------------------------
myList at start: [1, 2]
myInt  at start: 4
myList at end:   [1]
myInt  at end:   3
--------------------------------
myList at start: [1]
myInt  at start: 4
myList at end:   []
myInt  at end:   3

现在,根据关于如何在函数中处理默认参数的各种文章,myInt 似乎应该表现出与myList 相同的行为,即它应该递减到 3、2、1。但显然它没有。

如果我修改 doNotCare = myList.pop() 行,而不是使用切片来更新列表,难题会变得更加复杂:

class MyClass():
    def printStuff(self,myList=[1,2,3],myInt=4):
        print '--------------------------------'
        print 'myList at start: '+str(myList)
        print 'myInt  at start: '+str(myInt)
        myList = myList[:-1]
        myInt = myInt - 1
        print 'myList at end:   '+str(myList)
        print 'myInt  at end:   '+str(myInt)

testMC = MyClass()
testMC.printStuff()
testMC.printStuff()
testMC.printStuff()

...它以某种方式击败了那个意想不到的保留值,产生了输出:

--------------------------------
myList at start: [1, 2, 3]
myInt  at start: 4
myList at end:   [1, 2]
myInt  at end:   3
--------------------------------
myList at start: [1, 2, 3]
myInt  at start: 4
myList at end:   [1, 2]
myInt  at end:   3
--------------------------------
myList at start: [1, 2, 3]
myInt  at start: 4
myList at end:   [1, 2]
myInt  at end:   3

所以我想第一个问题是,这实际上只是参考中描述的默认参数行为的一个更复杂和微妙的情况吗?如果是,那么当我使用切片而不是pop 来操作它时,为什么该行为不适用于myInt 甚至myList

【问题讨论】:

标签: python-2.7 list class methods


【解决方案1】:

与列表不同,数字是不可变的,因此无法更改。可以重新分配对它们的引用,但 1 始终是 1。

拼接不会产生这种行为,因为它会创建原始列表的副本,而pop 会修改原始列表。

【讨论】:

  • 谢谢,这很有意义。所以元组也不会受到影响——只有列表、字典等。
  • @JDM 对。任何不可变的东西,包括元组,都是“安全的”。不过,您需要小心使用可变对象。
猜你喜欢
  • 2021-08-23
  • 1970-01-01
  • 2013-06-25
  • 1970-01-01
  • 2012-11-18
  • 1970-01-01
  • 2015-07-15
  • 2013-07-29
  • 2019-07-07
相关资源
最近更新 更多