题目一:以下的代码的输出将是什么? 说出你的答案并诠释。
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
使你疑心或是惊异的是关于末了一行的输出是 3 2 3 而不是 3 2 1。为何转变了 Parent.x 的值还会转变 Child2.x 的值,然则同时 Child1.x 值却没有转变?
这个答案的关键是,在 Python 中,类变量在内部是作为字典处置惩罚的。假如一个变量的名字没有在当前类的字典中发明,将搜刮先人类(比方父类)直到被援用的变量名被找到(假如这个被援用的变量名既没有在本身地点的类又没有在先人类中找到,会激发一个 AttributeError 非常 )。
因而,在父类中设置 x = 1 会使得类变量 X 在援用该类和其任何子类中的值为 1。这就是由于第一个 print 语句的输出是 1 1 1。
随后,假如任何它的子类重写了该值(比方,我们实行语句 Child1.x = 2),然后,该值仅仅在子类中被转变。这就是为何第二个 print 语句的输出是 1 2 1。
末了,假如该值在父类中被转变(比方,我们实行语句 Parent.x = 3),这个转变会影响到任何未重写该值的子类当中的值(在这个示例中被影响的子类是 Child2)。这就是为何第三个 print 输出是 3 2 3。
题目二:以下的代码的输出将是什么? 说出你的答案并诠释?
def p1(x,y): print("%s/%s = %s" % (x, y, x/y)) def p2(x,y): print("%s//%s = %s" % (x, y, x//y)) p1(5,2) p1(5.,2) p2(5,2) p2(5.,2.)
5/2 = 2 5.0/2.0=2.5 5/2=2 5/2=2
答案
这个答案现实依赖于你运用的是 Python 2 照样 Python 3。
在 Python 3 中,希冀的输出是:
5/2 = 2.5 5.0/2 = 2.5 5//2 = 2 5.0//2.0 = 2.0
在 Python 2 中,尽管如此,以上代码的输出将是:
5/2 = 2 5.0/2 = 2.5 5//2 = 2 5.0//2.0 = 2.0
默许,假如两个操纵数都是整数,Python 2 自动实行整型盘算。效果,5/2 值为 2,但是 5./2 值为 "2.5``。
注重,尽管如此,你能够在 Python 2 中重载这一行动(比方到达你想在 Python 3 中的一样效果),经由过程增加以下导入:
from__future__ import pision
也须要注重的是“双划线”(//)操纵符将一向实行整除,而不论操纵数的范例,这就是为何 5.0//2.0 值为 2.0。
注: 在 Python 3 中,/ 操纵符是做浮点除法,而 // 是做整除(即商没有余数,比方 10 // 3 其效果就为 3,余数会被截撤除,而 (-7) // 3 的效果倒是 -3。这个算法与别的许多编程言语不一样,须要注重,它们的整除运算会向0的方向取值。而在 Python 2 中,/ 就是整除,即和 Python 3 中的 // 操纵符一样,)
题目三:以下代码将输出什么?
list = ['a', 'b', 'c', 'd', 'e'] print list[10:]
答案
以上代码将输出 [ ],而且不会致使一个 IndexError。
正如人们所希冀的,试图接见一个凌驾列表索引值的成员将致使 IndexError(比方接见以上列表的 list[10])。尽管如此,试图接见一个列表的以超越列表成员数作为最先索引的切片将不会致使 IndexError,而且将仅仅返回一个空列表。
一个憎恶的小题目是它会致使涌现 bug ,而且这个题目是难以追踪的,由于它在运行时不会激发毛病。
题目四:以下的代码的输出将是什么? 说出你的答案并诠释?
def multipliers(): return [lambda x : i * x for i in range(4)] print [m(2) for m in multipliers()]
你将怎样修正 multipliers 的定义来发作希冀的效果
答案
以上代码的输出是 [6, 6, 6, 6] (而不是 [0, 2, 4, 6])。
这个的原因是 Python 的闭包的后期绑定致使的 late binding,这意味着在闭包中的变量是在内部函数被挪用的时刻被查找。所以效果是,当任何 multipliers() 返回的函数被挪用,在当时,i 的值是在它被挪用时的四周作用域中查找,到当时,不管哪一个返回的函数被挪用,for 轮回都已完成了,i 末了的值是 3,因而,每一个返回的函数 multiplies 的值都是 3。因而一个即是 2 的值被通报进以上代码,它们将返回一个值 6 (比方: 3 x 2)。
(趁便说下,正如在 The Hitchhiker’s Guide to Python 中指出的,这里有一点广泛的误会,是关于 lambda 表达式的一些东西。一个 lambda 表达式建立的函数不是特别的,和运用一个一般的 def 建立的函数展现的表现是一样的。)
这里有两种要领处理这个题目。
最广泛的处理方案是建立一个闭包,经由过程运用默许参数马上绑定它的参数。比方:
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)]
题目五:以下的代码的输出将是什么? 说出你的答案并诠释?
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
你将怎样修正 extendList 的定义来发作希冀的效果
以上代码的输出为:
list1 = [10, 'a'] list2 = [123] list3 = [10, 'a']
许多人会毛病的以为 list1 应当即是 [10] 以及 list3 应当即是 [‘a’]。以为 list 的参数会在 extendList 每次被挪用的时刻会被设置成它的默许值 [ ]。
尽管如此,现实发作的事变是,新的默许列表仅仅只在函数被定义时建立一次。随后当 extendList 没有被指定的列表参数挪用的时刻,其运用的是同一个列表。这就是为何当函数被定义的时刻,表达式是用默许参数被盘算,而不是它被挪用的时刻。
因而,list1 和 list3 是操纵的雷同的列表。而 "`list2是操纵的它建立的自力的列表(经由过程通报它本身的空列表作为list"参数的值)。
extendList 函数的定义能够做以下修正,但,当没有新的 list 参数被指定的时刻,会老是最先一个新列表,这越发多是一向希冀的行动。
def extendList(val, list=None): if list is None: list = [] list.append(val) return list
运用这个革新的完成,输出将是:
list1 = [10] list2 = [123] list3 = ['a']
以上就是python口试中必考的代码题的细致内容,更多请关注ki4网别的相干文章!