难度指数: ★★★
重要指数: ★★★
题目要求
问题一:以下的代码的输出将是什么? 说出你的答案并解释。
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
考察点
这个问题考察的是你对类属性的理解,x是Parent 的类属性,Child1 和 Child2 虽然继承了Parent, 但他们两个都没有x这个属性,这一点可以通过print(Child1.__dict__)来证明,既然Child1 和 Child2 没有x属性,为什么能输出Child1.x呢? 这是因为当在Child1中招不到x这个属性时就会去它的父类中去寻找,这样就找打了Parent.x
执行了Child1.x = 2 , 就相当于为Child1 这个类增加了x属性,下次输出Child1.x时结果就是2,但 Child2 仍然没有x属性,因此得到依然是Parent.x 的值
难度指数: ★★★
重要指数: ★★★★★
题目要求:
以下的代码的输出将是什么? 说出你的答案并解释?
def multipliers():
return [lambda x : i * x for i in range(4)]
print [m(2) for m in multipliers()]
有些人可能会回答[0, 2, 4, 6], 有些人则干脆不知道如何回答,正确的答案是[6, 6, 6, 6]
这个题目考察了lambda的用法,和闭包的概念,且听我娓娓道来。
lst = multipliers()
print(lst) # <function multipliers.<locals>.<listcomp>.<lambda> at 0x00000254D6C85BF8>
这段代码是上面三点说明的一个印证,现在的关键是确定这4个函数中i的值是多少,有人坚持认为lst[0]这个函数中i的值是0, lst[1]这个函数中的i是1, 因为创建这个函数的过程中,i参与了for循环,i的值就是从0 变化到 3,这样理解只对了一半,我们要明白,生成的这4个函数都是闭包,而闭包内的i是对外部作用域里i的一个引用,当for循环结束时,i的值已经变成3, 因此这4个函数内的i都是3。
解决了multipliers的返回值和列表里函数内部的i的取值问题,再来看最后一步
print([m(2) for m in multipliers()])
仍然是一个列表推导式,for循环过程中,对multipliers函数返回的列表进行遍历,m就是列表里的函数,传入的x = 2, 而i等于3, 2*3 = 6, 因此最终结果是[6, 6, 6, 6]
难度指数: ★★
重要指数: ★★★★
题目要求:
实现下面的函数
import os
def print_directory_contents(path):
"""
输出文件夹中的文件路径,如果文件夹中存在文件夹,则向深层遍历
:param path:
:return:
"""
pass
工作中,遍历文件夹的操作还是比较常见的,这个题目考察的是你对os.path这个模块的掌握以及对递归函数的理解运用能力,这种题目,只有靠多练了
import os
def print_directory_contents(path):
"""
输出文件夹中的文件路径,如果文件夹中存在文件夹,则向深层遍历
:param path:
:return:
"""
for chlid in os.listdir(path):
chlid_path = os.path.join(path, chlid)
if os.path.isdir(chlid_path): # 如果chlid_path 是文件夹
print_directory_contents(chlid_path)
else:
print(chlid_path)
这三个函数一定要掌握
难度指数: ★★★
重要指数: ★★★★
题目要求:
阅读下面的代码,写出A0,A1至An的最终值
A0 = dict(zip(('a','b','c','d','e'),(1,2,3,4,5)))
A1 = range(10)
A2 = [i for i in A1 if i in A0]
A3 = [A0[s] for s in A0]
A4 = [i for i in A1 if i in A3]
A5 = {i:i*i for i in A1}
A6 = [[i,i*i] for i in A1]
这个题目要考察的,是你对推导式的理解,以及zip,range 这两个内置函数的理解
对A0的理解
先来看这行代码
print(dict([(3, 4)])) # {3: 4}
dict 函数可以将一个可迭代对象转为字典,只要能满足下面的形式
dict(iterable) -> new dictionary initialized as if via:
d = {}
for k, v in iterable:
d[k] = v
[(3, 4)],这个列表里的元素是元组,且元组里有两个元素,满足for k, v in iterable这样的语句要求。
zip(('a','b','c','d','e'),(1,2,3,4,5)) 返回的,也是一个可迭代对象
for key, value in zip(('a','b','c','d','e'),(1,2,3,4,5)):
print(key, value)
也满足dict函数的参数要求,因此可以转换为字典,其结果是{'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
A1的理解
python2中range函数返回的是一个列表,但在python3中,是一个生成器,print出来的结果就是 range(10)
A2的理解
[i for i in A1 if i in A0] , 要拆分三部分来看
第一部分, i
第二部分, for i in A1
第三部分, if i in A0
对A1 进行比例,如果 i 在A0中,那么就放入到列表中, 理解的顺序是2, 3, 1, 由于字典的key都是字符串,第二部分循环时,i的值都是int类型,不在字典中,A2 的结果空列表
A3的理解
[A0[s] for s in A0], 拆成两部分
第一部分, A0[s]
第二部分, for s in A0
对A0进行遍历,获取A0[S]的值放入列表中,理解的顺序是 2 1, 结果过是[1, 2, 3, 4, 5]
A4的理解
[i for i in A1 if i in A3], 拆成三部分
第一部分, i
第二部分, for i in A1
第三部分, if i in A3
对A1进行遍历,如果i 在A3中,则将i放入列表中, 理解顺序是2 3 1, 第二部分进行for循环时产生的整数从0到9,只有1到5在A3中,因此最终结果是 [1, 2, 3, 4, 5]
A5的理解
{i:ii for i in A1} 这是一个字典推导式,拆成两部分理解
第一部分, i:ii
第二部分, for i in A1
对A1进行遍历,将key-value对 i: i*i方法字典中,理解顺序是2 1, 遍历过程中,i从0变化到9, 以i等于5为例,5:5*5 放入字典中,key=5, value=25, 最终结果是{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}
A6的理解
[[i,ii] for i in A1] ,拆成两部分理解
第一部分, [i,ii]
第二部分, for i in A1
对A1 进行遍历,i从0变化到9, 以i= 5为例,生成的数据是[5, 25], 将[5, 25]放入列表中,最终结果是[[0, 0], [1, 1], [2, 4], [3, 9], [4, 16], [5, 25], [6, 36], [7, 49], [8, 64], [9, 81]]
难度指数: ★★★
重要指数: ★★★★
题目要求:
下面代码会输出什么?
def f(x, lst=[]):
for i in range(x):
lst.append(i*i)
print(lst)
f(2)
f(3, [3, 2, 1])
f(3)
f(2) 输出 [0, 1]
f(3, [3, 2, 1]) 输出 [3, 2, 1, 0, 1, 4]
这两个都比较好理解,难理解的是f(3),不懂的人认为应该输出[0, 1, 4], 但实际结果是[0, 1, 0, 1, 4] , 多出了0 和 1, 原因在当可变对象作为函数的参数的默认值时,只会在函数定义的时候创建一次,此后,如果这个如果你不传这个参数,那么就使用默认的参数值,但这个值只创建一次,f(2) 和 f(3) 两次调用时用的都是同一个列表,f(2)执行时已经向列表里添加0,1, f(3) 执行时,又加入了0 ,1 , 4 ,因此最终结果是[0, 1, 0, 1, 4]
难度指数: ★★★
重要指数: ★★★★
题目要求:
写出下面代码的执行结果
class A(object):
def go(self):
print("go A go!")
def stop(self):
print("stop A stop!")
def pause(self):
raise Exception("Not Implemented")
class B(A):
def go(self):
super(B, self).go()
print("go B go!")
class C(A):
def go(self):
super(C, self).go()
print("go C go!")
def stop(self):
super(C, self).stop()
print("stop C stop!")
class D(B,C):
def go(self):
super(D, self).go()
print("go D go!")
def stop(self):
super(D, self).stop()
print("stop D stop!")
def pause(self):
print("wait D wait!")
class E(B,C): pass
a = A()
b = B()
c = C()
d = D()
e = E()
# 说明下列代码的输出结果
a.go()
b.go()
c.go()
d.go()
e.go()
a.stop()
b.stop()
c.stop()
d.stop()
e.stop()
a.pause()
b.pause()
c.pause()
d.pause()
e.pause()
这个题目考察的是多继承与super用法,首先要明确,这个继承关系里出现了菱形继承
A
B C
D/E
先来看go方法调用
再来看stop方法调用
最后来看pause方法调用
QQ交流群: 211426309