Essential Python Interview Questions
1) extendList
下面这段代码的输出是什么?
#!/usr/bin/python3 # -*- coding: UTF-8 -*- def extendList(val, list=[]): list.append(val) return list list1 = extendList(10) list2 = extendList(123,[]) list3 = extendList('a') print "list1 = %s" % list1 print "list2 = %s" % list2 print "list3 = %s" % list3
这段代码的关键点是函数的参数是list类型时,它的默认值list只在函数定义时赋值给参数。如果调用函数时没有传入list参数,那么每次调用使用的是相同的list。
所以list1和list2没有传入list参数,它们使用相同的list。而list2用的是自己传入的list。
输出结果如下:
list1 = [10, 'a'] list2 = [123] list3 = [10, 'a']
为了实现预想的效果,修改函数如下:
def extendList(val, list=None): if list is None: list = [] list.append(val) return list
2) multipliers
下面这段代码的输出是什么?
#!/usr/bin/python3 # -*- coding: UTF-8 -*- def multipliers(): return [lambda x: i * x for i in range(4)] print ([m[2] for m in multipliers()])
这段代码的输出是[6,6,6,6],而不是[0,2,4,6]。
因为python的late binding,所以调用multipliers()返回的函数时,i的值在函数的作用域外查找,此时for循环已经完成,i的值为3。因此multipliers()返回的所有函数的i值都是3。
为了解决这个问题,有两种方法:
1)使用generator
def multipliers(): for i in range(4): yield lambda x : i * x
2) 使用默认参数来绑定i值
def multipliers(): return [lambda x, i=i : i * x for i in range(4)]
或者使用functools.partial函数:
from functools import partial from operator import mul def multipliers(): return [partial(mul, i) for i in range(4)]
3) Child Class Attributes
下面这段代码的输出是什么?
#!/use/bin/python3 # -*- coding: UTF-8 -*- class Parent(object): x = 1 class Child1(Parent): pass class Child2(Parent): pass print (Parent.x, Child1.x, Child2.x) Child1.x = 2 print (Parent.x, Child1.x, Child2.x) Parent.x = 3 print (Parent.x, Child1.x, Child2.x)
输出是
1 1 1
1 2 1
3 2 3
Python用dict来存储类的变量,如果当前类不能找到变量,则向父类查找变量。如果最终没有找到,会产生AttributeError错误。所以第一行打印1 1 1。
如果子类改变了变量的值,只会改变子类的变量,不会影响父类。所以第二行打印1 2 1。
如果父类改变了变量值,也会反映到子类中没有改变值的变量。所以第三行打印3 2 3。
4) Division
下面这段Python2代码的输出是什么?
#!/usr/bin/python # -*- coding: UTF8 -*- def div1(x, y): print "%s/%s = %s" % (x, y, x/y) def div2(x, y): print "%s//%s = %s" % (x, y, x//y) div1(5, 2) div1(5., 2) div2(5, 2) div2(5., 2.)
输出是
5/2 = 2
5.0/2 = 2.5
5//2 = 2
5.0//2.0 = 2.0
如果操作数都是int类型,Python2 默认结果也是int类型。但是Python3不会。
Python3的输出为
5/2 = 2.5
5.0/2 = 2.5
5//2 = 2
5.0//2.0 = 2.0
注意,操作符//总是做整数运算。