试题来源:Python之美 答案作者:古明地觉 第一题 问题: 答案解析: 这道题答案选择 A,可以根据排除法,B C D 都是错误的。那么下面分析一下,为什么它们是错误的。 首先 Python 有一个模块叫 builtins,像内置的类、内置函数等等都在里面。
所以 __builtins__ 已经指向了一个模块,因此 B 选项错误,而 import builtins 是正确的。同理 C 选项也是错误的,它是个干扰项。 最后是 D 选项,import 的后面应该是 __future__,不是 __futures__。那么这个模块是做什么的呢?我们知道 Python3 和 Python2 是不兼容的,比如 print 在 Python2 里面是一个关键字,但在 Python3 里面就是一个普通的内置函数。 而 __future__ 可以将 Python3 的特性导入到 Python2 中,方便代码兼容,举个例子:
所以通过排除法,可以排除 B C D,那么正确选项 A 是咋回事呢。其实这是官方玩的一个小彩蛋:
导入之后会自动打印 Hello world,我们通过 CPython 源码可以找到它,位于 Python/frozen.c 中。 可以看到里面不仅定义了 __hello__,还定义了 __phello__。
打印的结果是一样的。 第二题 问题: 答案解析: 这个问题在上一篇文章中我们说过:
所以 x 为 (0, 1),y 为 None,因此答案选择 C。 第三题 问题: 答案解析: 这道题的答案可能让人有些费解,我直接说结论:
所以答案为 D,会抛出 NameError。因为在异常处理的时候,如果把异常赋予了一个变量,那么这个变量在异常处理结束时会被删掉,因此变量 e 只能在 except 里面使用。 当使用 as 将异常赋值给一个变量时,该变量将在 except 子句结束时被清除,这意味着异常必须赋值给一个不同的名称(不同于外部指定的变量),才能在 except 子句之后引用它(外部指定的变量)。 而变量被清除是因为在附加了回溯信息的情况下,它们会形成堆栈帧的循环引用,在下一次垃圾回收执行之前,会使所有局部变量都保持存活。 说人话就是,如果不将 as 后面的变量删除,那么会多一次 GC。 既然此处提到了异常处理,这里就再补充一个很多人应该不知道的知识点。
按理说,except 无法捕获 try 里面引发的异常,那么应该报错才对啊,为啥这里没报错呢。 首先 finally 子句始终会被执行,它应该负责一些资源清理等善后工作,如果 except 子句没有成功捕获异常,那么 finally 子句执行结束后会再将异常抛出来。但如果 finally 里面出现了 return、break、continue 等关键字,那么异常就不会抛出来了,而是会被丢弃掉。 第四题 问题: 答案解析: 这道题还是考察了海象运算符。
所以答案为 B,比较简单。 第五题 问题: 答案解析: 这里先补充一个知识点,Python 的变量从 C 的角度来看只是一个泛型指针。比如 a = 1,实际上是先创建整数 1,然后再让变量 a 保存整数 1 的地址。所以 Python 里面一定是先有对象,然后才有变量。 对于 for 循环来说亦是如此,先将可迭代对象里面的值迭代出来,然后再将值赋给循环变量。所以上面的循环相当于做了如下事情:
所以答案是 A,循环体里面的 i = i + 1 没有意义,因为每次循环都会对变量 i 重新赋值。 第六题 问题: 答案解析: 这道题乍一看可能有点让人纳闷,其实这道题主要考察的是内置函数 reversed。它和 sorted 不同,reversed 返回的不是一个列表,而是一个迭代器。 而迭代器只能顺序遍历一次,所以 == 左边的 sorted(y) 是 [7, 8, 9],右边的 sorted(y) 是空列表,因此结果是 False,答案是 B。 第七题 问题: 答案解析: 这道题实际上还是考察了对 Python 变量的理解,对于 Go 这样的静态语言来说,变量就是对象所在内存的别名,比如 a = 123,a 对应的内存存储的就是 123 本身。但 Python 不同,对于 Python 而言,a = 123,a 对应的内存存储的是整数 123 的内存地址。
所以说 Python 是值传递或引用传递都是不准确的,应该说 Python 是变量的赋值传递,对象的引用传递。因为 Python 的变量代表的不是对象本身,而是对象的指针(准确的说是引用)。
所以题目就很简单了,b = a 之后,两个变量都指向了 [1, 2, 3]。而 a = a + [4, 5, 6] 相当于对 a 重新赋值了,让 a 指向了新的列表,但 b 不受影响,所以答案是 A。 如果将问题再改一下,将第三行代码改成 a += [4, 5, 6],那么结果就会发生改变,答案就变成了 B。
所以列表的 += 比较特殊,要注意。 第八题 问题: 答案解析: 这个没什么可说的,答案是 C。 第九题 问题: 答案解析:
没什么可说的,答案是 C。 第十题 问题: 答案解析: 对于一个生成器而言,迭代出来的是 yield 后面的值。
而生成器的返回值需要手动捕获 StopIteration 异常,然后调用它的 value 属性才能拿到。
所以答案很清晰了,答案选 C。 小结 本试题来源于 《Python 之美》,总的来说问题很不错,后续还有更新的话,我再继续解答。 |
|