09月22日, 2014 166次
异的行为与Python中可变对象和不可变对象之间的区别有关怎么办?
诸如列表,集合或字典之类的可变对象可以在适当位置进行更改(变异)。 不变的对象(如整数,字符串和元组)不能 mdash;此类对象的 更改 会导致创建新对象。
问题1的说明
x = 1 y = 2 l = [x, y] x += 5 a = [1] b = [2] s = [a, b] a.append(5) print(l) [1, 2] print(s) [[1, 5], [2]]由于x是不可变的,因此操作x + = 5不会更改原始对象,而是创建一个新对象。 列表的第一个元素仍指向原始对象,因此其值保持不变。
对于可变对象a,a.append(5)更改原始对象,因此list s 看到 更改。
问题2的解释
def f(x, s=set()): s.add(x) print(s) f(7) {7} f(6, {4, 5}) {4, 5, 6} f(2) {2, 7}前两个输出完全有意义:首先将值7添加到默认空集中,得到{7},然后将值6添加到一组{4,5}中,得到{4,5,6 }。
但是随后发生了一件奇怪的事情:将值2添加到默认的空集而不是添加到{7}的集。 为什么? 可选参数s的默认值仅被评估一次-仅在第一次调用s期间将被初始化为空集。 由于s在调用f(7)之后是可变的,因此就地进行了修改。 第二个调用f(6,{4,5})不会影响默认参数-提供的集合{4,5}将其遮蔽,换句话说,{4,5}是一个不同的变量。 第三次调用f(2)使用的是与第一次调用相同的s变量,但是s未作为空集重新初始化-使用了其先前的值{7}。
这就是为什么您不应该使用可变的默认参数的原因。 在这种情况下,应按以下方式修改功能:
def f(x, s=None): if s is None: s = set() s.add(x) print(s)问题3的解释
def f(): l = [1] def inner(x): l.append(x) return l return inner def g(): y = 1 def inner(x): y += x return y return inner ff_inner = f() print(f_inner(2)) [1, 2] gg_inner = g() print(g_inner(2)) UnboundLocalError: local variable lsquo;y rsquo; referenced before assignment在这个问题中,我们处理闭包-内部函数记住定义时它们的封闭名称空间的外观。 或至少应该如此-第二个功能保持扑克面孔,就像从未听说过其外部作用域一样。
这是为什么? 当我们执行l.append(x)时,在定义时创建的可变对象被修改,但是变量l仍然指向内存中的相同地址。 但是,尝试更改第二个函数y + = x中的不可变变量会导致y指向内存中与以前不同的地址-原始y将不再被记住,因此导致UnboundLocalError。
到此,相信大家对“3个看似简单的Python问题是什么”有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!