尝试解决以下问题,然后检查以下答案。
公司主营业务:成都网站设计、成都网站制作、移动网站开发等业务。帮助企业客户真正实现互联网宣传,提高企业的竞争能力。创新互联是一支青春激扬、勤奋敬业、活力青春激扬、勤奋敬业、活力澎湃、和谐高效的团队。公司秉承以“开放、自由、严谨、自律”为核心的企业文化,感谢他们对我们的高要求,感谢他们从不同领域给我们带来的挑战,让我们激情的团队有机会用头脑与智慧不断的给客户带来惊喜。创新互联推出乌苏免费做网站回馈大家。
提示:所有问题都有共同点,因此在解决其余问题之前检查第一个问题的解决方案可以减轻挑战。
问题1
假设我们有几个变量:
- x = 1
- y = 2
- l = [x, y]
- x += 5
- a = [1]
- b = [2]
- s = [a, b]
- a.append(5)
l和s的打印结果是什么?
跳到解决方案
问题2
让我们定义一个简单的函数:
- def f(x, s=set()):
- s.add(x) print(s)
如果您决定,将会发生什么:
- >>f(7)
- >>f(6, {4, 5})
- >>f(2)
- ?
跳到解决方案
问题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))
- >>gg_inner = g()
- >>print(g_inner(2))
跳到解决方案
您对自己的回答有多自信? 让我们看看您是否正确。
解决问题1
- >>print(l)
- [1, 2]
- >>print(s)
- [[1, 5], [2]]
为什么第二个列表对第一个元素a.append(5)的更改有反应,但是第一个列表完全忽略x + = 5的类似变化?
解决问题2
让我们看看发生了什么:
- >>f(7){7}
- >>f(6, {4, 5}){4, 5, 6}
- >>f(2){2, 7}
等待,最后输出不是{2}吗?
解决问题3
输出将是以下内容:
- >>ff_inner = f()
- >>print(f_inner(2))[1, 2]
- >>gg_inner = g()
- >>print(g_inner(2))
- UnboundLocalError: local variable 'y' referenced before assignment
为什么g_inner(2)不输出3? f()的内部函数如何记住其外部范围,而g()的内部函数却不记得呢? 它们实际上是相同的!
说明
如果我告诉您这些怪异的行为与Python中可变对象和不可变对象之间的区别有关怎么办?
诸如列表,集合或字典之类的可变对象可以在适当位置进行更改(变异)。 不变的对象(如整数,字符串和元组)不能—此类对象的"更改"会导致创建新对象。
问题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 ‘y’ referenced before assignment
在这个问题中,我们处理闭包-内部函数记住定义时它们的封闭名称空间的外观。 或至少应该如此-第二个功能保持扑克面孔,就像从未听说过其外部作用域一样。
这是为什么? 当我们执行l.append(x)时,在定义时创建的可变对象被修改,但是变量l仍然指向内存中的相同地址。 但是,尝试更改第二个函数y + = x中的不可变变量会导致y指向内存中与以前不同的地址-原始y将不再被记住,因此导致UnboundLocalError。
结论
Python中可变对象与不可变对象之间的区别非常重要。 请注意这一点,以避免出现本文所述的奇怪行为。 特别是:
网站名称:您能解决这3个(看似)简单的Python问题吗?
新闻来源:http://www.csdahua.cn/qtweb/news32/296832.html
网站建设、网络推广公司-快上网,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 快上网