问题一:以下的代码的输出将是什么? 说出你的答案并解释。

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:]

答案

以上代码将输出 [],并且不会导致一个 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 面试题2的更多相关文章

  1. Python面试题 —— 获取列表中位数

    中位数是一个可将数值集合划分为相等的上下两部分的一个数值.如果列表数据的个数是奇数,则列表中间那个数据就是列表数据的中位数:如果列表数据的个数是偶数,则列表中间那2个数据的算术平均值就是列表数据的中位 ...

  2. python公司面试题集锦 python面试题大全

    问题一:以下的代码的输出将是什么? 说出你的答案并解释. class Parent(object): x = 1 class Child1(Parent): pass class Child2(Par ...

  3. 【Python】【面试必看】Python笔试题

    前言 现在面试测试岗位,一般会要求熟悉一门语言(python/java),为了考验求职者的基本功,一般会出 2 个笔试题,这些题目一般不难,主要考察基本功.要是给你一台电脑,在编辑器里面边写边调试,没 ...

  4. Python面试题整理-更新中

    几个链接: 编程零基础应当如何开始学习 Python ? - 路人甲的回答 网易云课堂上有哪些值得推荐的 Python 教程? - 路人甲的回答 怎么用最短时间高效而踏实地学习 Python? - 路 ...

  5. python 面试题4

    Python面试题 基础篇 分类: Python2014-08-08 13:15 2071人阅读 评论(0) 收藏 举报 最近,整理了一些python常见的面试题目,语言是一种工具,但是多角度的了解工 ...

  6. 一道Python面试题

    无意间,看到这么一道Python面试题:以下代码将输出什么? def testFun():    temp = [lambda x : i*x for i in range(4)]    return ...

  7. 很全的 Python 面试题

    很全的 Python 面试题 Python语言特性 1 Python的函数参数传递 看两个例子:           Python   1 2 3 4 5 a = 1 def fun(a):      ...

  8. SQL + Python 面试题:之二(难度:中等)

    SQL + Python 面试题:之二(难度:中等)

  9. Python面试题之一:解密

    Python面试题之一: 说明:就是Python工程师面试题 一.字典转换与正则提取值 1:key与Value交换 a = {'a':1,'b':2} print({value:key for key ...

  10. 震惊!几道Python 理论面试题,Python面试题No18

    本面试题题库,由公号:非本科程序员 整理发布 第1题: 简述解释型和编译型编程语言? 解释型语言编写的程序不需要编译,在执行的时候,专门有一个解释器能够将VB语言翻译成机器语言,每个语句都是执行的时候 ...

随机推荐

  1. 我的虚拟机中的 centOS 连不了网了

    网上的办法试过了,查看虚拟机的网络配置,是 NET的, 也 cd 到/etc/sysconfig/network-script/ifcfg-eth0 里面看了,onboot 本来就是 yes,要不然我 ...

  2. forEach遍历数组对象且去重

    forEach遍历数组对象 var obj1 = [{ key: '01', value: '哈哈' }, { key: '02', value: '旺旺' }, { key: '03', value ...

  3. Dapper 事务处理

    例子: using (var connection = GetOpenConnection()) using (var transaction = connection.BeginTransactio ...

  4. SPOJ IM_Intergalactic Map

    判断能否从一个点同时找出两条不相交的路径到另外两个点. 保证路径不相交,那么需要拆点.然后?好像就没什么了,直接最大流即可. 不过,,,不需要求出所有的最大流,只要跑两次EK看看能否增广两次就行了. ...

  5. java递归方法求数组最大元素

    一直对递归写法不是很熟悉,特写一个增进理解 /** * Created by Administrator on 2017-11-01. */ public class recursion { priv ...

  6. Springboot+Thymeleaf框架的button错误

    ---恢复内容开始--- 在做公司项目时,遇到了一个Springboot+Thymeleaf框架问题: 使用框架写网站时,没有标明type类型的button默认成了‘submit’类型,每次点击按钮都 ...

  7. Alpha 完结撒花 —— 事后诸葛亮

    写在前面 林燊大哥 一路走来,好不容易,终于完结了. 设想和目标 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? 解决的问题 用户在进店之前无法得知店铺的优劣,通过 ...

  8. Cobalt Strike 3.13的新功能

    Cobalt Strike 3.13现已推出.此版本添加了TCP Beacong,进程参数欺骗,并将Obfuscate和Sleep功能扩展到SMB和TCP Beacons. TCP Beacon Co ...

  9. 《Linux内核设计与实现》学习总结 Chap3

    第三章 进程管理 进程是Unix操作系统抽象概念中最基本的一种.我们拥有操作系统就是为了运行用户程序,因此,进程管理就是所有操作系统的心脏所在. 3.1进程 概念: 进程:处于执行期的程序.但不仅局限 ...

  10. typescript数据类型

    // 布尔类型 let isDone: boolean = false; // 数字类型 所有数字都是浮点数 number let decLiteral: number = 6; let hexLit ...