英文:toptal
译文:yexiaobai
链接:segmentfault.com/a/1190000000618513
注:本文的原文是 5 Great Python Interview Questions,同时谢谢 @非乌龟 指出我的疏漏,没有来源标记,也赞其细心,希望看文章的同时大家都能看下原文,因为每个人的理解不一致,原汁原味的最有帮助,我翻译很多文章的目的一是为了自己以后找资料方便;二是作为一个索引,以后再看原文的时候,能更加快捷。其目的还是希望大家能看原文的。
问题一:以下的代码的输出将是什么? 说出你的答案并解释。
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 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.
)
答案
这个答案实际依赖于你使用的是 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
division
也需要注意的是“双划线”(//)操作符将一直执行整除,而不管操作数的类型,这就是为什么 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
: