1. 类继承

如下代码

class A(object):def show(self):print 'This is calss A'class B(A):def show(self):print 'This is calss B'obj = B()
obj.show()

如何才能调用类 A 的 show 方法呢?

obj.__class__ = A
obj.show()

__ class __ 方法指向了类对象,只用给他赋值类型 A,然后调用方法 show,但是用完了记得修改回来。

2. 方法对象

问题:为了让下面这段代码运行,需要增加哪些代码?

class A(object):def __init__(self,a,b):self.__a = aself.__b = bdef myprint(self):print 'a=', self.__a, 'b=', self.__ba1=A(10,20)
a1.myprint()a1(80)

答案:为了能让对象实例能被直接调用,需要实现__ call __ 方法

class A(object):def __init__(self, a, b):self.__a = aself.__b = bdef myprint(self):print 'a=', self.__a, 'b=', self.__bdef __call__(self, num):print 'call:', num + self.__a

3. __ new __ 和 __ init __

下面这段代码输出什么?

class B(object):def fn(self):print 'B fn'def __init__(self):print "B INIT"class A(object):def fn(self):print 'A fn'def __new__(cls,a):print "NEW", aif a>10:return super(A, cls).__new__(cls)return B()def __init__(self,a):print "INIT", aa1 = A(5)
a1.fn()
a2=A(20)
a2.fn()

输出结果:

NEW 5
B INIT
B fn
NEW 20
INIT 20
A fn

使用__ new __ 方法,可以决定返回那个对象,也就是创建对象之前,这个可以用于设计模式的单例、工厂模式。__ init __ 是创建对象是调用的。

4. 默认方法

如下代码:

class A(object):def __init__(self,a,b):self.a1 = aself.b1 = bprint 'init'def mydefault(self):print 'default'a1 = A(10,20)
a1.fn1()
a1.fn2()
a1.fn3()

方法 fn1/fn2/fn3 都没有定义,怎样修改代码,使得没有定义的方法都调用 mydefault 函数,上面的代码应该输出

default
default
default

答案如下:

class A(object):def __init__(self,a,b):self.a1 = aself.b1 = bprint 'init'def mydefault(self):print 'default'def __getattr__(self,name):return self.mydefaulta1 = A(10,20)
a1.fn1()
a1.fn2()
a1.fn3()

方法__ getattr __ 只有当没有定义的方法调用时,才是调用他。当 fn1 方法传入参数时,我们可以给mydefault 方法增加一个 *args 不定参数来兼容。

class A(object):def __init__(self,a,b):self.a1 = aself.b1 = bprint 'init'def mydefault(self,*args):print 'default:' + str(args[0])def __getattr__(self,name):print "other fn:",namereturn self.mydefaulta1 = A(10,20)
a1.fn1(33)
a1.fn2('hello')
a1.fn3(10)

输出结果如下:

init
other fn: fn1
default:33
other fn: fn2
default:hello
other fn: fn3
default:10

5. 包管理

一个包里有三个模块,mod1.py, mod2.py, mod3.py,但使用 from demopack import * 导入模块时,如何保证只有 mod1、mod3 被导入了。

答案:增加__ init __.py 文件,并在文件中增加:

__all__ = ['mod1','mod3']

6. 闭包

写一个函数,接收整数参数n,返回一个函数,函数的功能是把函数的参数和n相乘并把结果返回。

In [8]: def fun(n):...:     def g(val):...:         return n * val...:     return g...: ...: ff = fun(7)...: print(ff(9))...:
63

7. 可变类型作为函数默认参数

下面代码输出结果是什么?

def extendList(val, list=[]):list.append(val)return listlist1 = extendList(10)
list2 = extendList(123,[])
list3 = extendList('a')print "list1 = %s" % list1
print "list2 = %s" % list2
print "list3 = %s" % list3

输出结果为:

list1 = [10, 'a']
list2 = [123]
list3 = [10, 'a']

很多人都会误认为 list1=[10], list3=[‘a’],因为他们以为每次 extendList 被调用时,列表参数的默认值都将被设置为[].但实际上的情况是,新的默认列表只在函数被定义的那一刻创建一次。当 extendList 被没有指定特定参数list调用时,这组list的值随后将被使用。这是因为带有默认参数的表达式在函数被定义的时候被计算,不是在调用的时候被计算。
因此 list1 和 list3 是在同一个默认列表上进行操作(计算)的。而 list2 是在一个分离的列表上进行操作(计算)的。(通过传递一个自有的空列表作为列表参数的数值)。

extendList 的定义可以作如下修改。尽管,创建一个新的列表,没有特定的列表参数。

下面这段代码可能能够产生想要的结果。

def extendList(val, list=None):if list is None:list = []list.append(val)return list

通过上面的修改,输出结果将变成:

list1 = [10]
list2 = [123]
list3 = ['a']

8. 超出成员个数的切片

下面代码输出的结果是什么?

list = ['a', 'b', 'c', 'd', 'e']
print list[10:]

输出结果为:

[]

例如,尝试获取list[10]和之后的成员,会导致 IndexError。
然而,尝试获取列表的切片,开始的index超过了成员个数不会产生 IndexError,而是仅仅返回一个空列表。
这成为特别让人恶心的疑难杂症,因为运行的时候没有错误产生,导致bug很难被追踪到。

9. 列表的引用

有以下代码

1. list = [ [ ] ] * 5
2. list  # output?
3. list[0].append(10)
4. list  # output?
5. list[1].append(20)
6. list  # output?
7. list.append(30)
8. list  # output?

2,4,6,8行的输出结果如下:

[[], [], [], [], []]
[[10], [10], [10], [10], [10]]
[[10, 20], [10, 20], [10, 20], [10, 20], [10, 20]]
[[10, 20], [10, 20], [10, 20], [10, 20], [10, 20], 30]

原因如下:

第一行的输出结果直觉上很容易理解,例如 list = [ [ ] ] * 5 就是简单的创造了5个空列表。
然而,理解表达式list=[ [ ] ] * 5的关键一点是它不是创造一个包含五个独立列表的列表,而是它是一个创建了包含对同一个列表五次引用的列表。
只有了解了这一点,我们才能更好的理解接下来的输出结果。

list[0].append(10) 将10附加在第一个列表上。

但由于所有5个列表是引用的同一个列表,所以这个结果将是:

[[10], [10], [10], [10], [10]]

同理,list[1].append(20)将20附加在第二个列表上。但同样由于5个列表是引用的同一个列表,所以输出结果现在是:

[[10, 20], [10, 20], [10, 20], [10, 20], [10, 20]]

作为对比, list.append(30)是将整个新的元素附加在外列表上,因此产生的结果是:

[[10, 20], [10, 20], [10, 20], [10, 20], [10, 20], 30]

10. L.sort() 与 sorted() 的区别

L.sort(cmp=None, key=None, reverse=False)sorted(iterable, cmp=None, key=None, reverse=False)
  • L.sort():该函数的三个参数和 sorted() 的后三个参数含义是一致的,而需要特别注意的是,该函数只适用于列表,而非任意可以迭代的对象。cmp 是比较函数,接受两个对象参数 x 和 y,返回 负数(x<y),0(x=y),正数(x>y)。
  • 该函数第一个参数 iterable 为任意可以迭代的对象,cmp 是比较函数,通常为lambda函数,key 是用于比较的关键字,reverse表示排序结果是否反转。
In [10]: aa = [5,4,3,2,1]In [11]: aa.sort()In [12]: aa
Out[12]: [1, 2, 3, 4, 5]

调用 sort() 之后会改变原来的表的结构顺序。

可以指定关键字排序

student = [['Tom', 'A', 20], ['Jack', 'C', 18], ['Andy', 'B', 11]]
student.sort(key=lambda student: student[2])## 输出结果
[['Andy', 'B', 11], ['Jack', 'C', 18], ['Tom', 'A', 20]]

sorted() 可以应用于任意的可以迭代的对象,所以应用范围比 L.sort() 广泛的多,可以应用于字符串,元组,列表,字典等可迭代对象。

In [19]: s = "zyx"In [20]: sorted(s)
Out[20]: ['x', 'y', 'z']In [21]: s
Out[21]: 'zyx'

需要注意的是,该函数会返回一个排序后的列表,原有可迭代对象保持不变,这与 L.sort() 函数不同。然而,这会浪费较大的存储空间,尤其是数据量较大时。所以,在列表进行排序时,需要考虑是否需要保存原列表,如果无需保存原列表,则优先使用L.sort() 节省内存空间,提高效率

  • L.sort() 函数只适用于列表排序,而sorted()函数适用于任意可以迭代的对象排序。
  • L.sort() 函数排序会改变原有的待排序列表,而sorted()函数则不会改变。所以在使用列表进行排序时,需要考虑是否需要保存原列表,如果无需保存原列表,则优先使用L.sort() 节省内存空间,提高效率。
  • 两个函数通过定义 key 和 cmp 都可以完成排序,但是 key 的效率要远远高于 cmp,所以要优先使用 key 。

11. append 与 extend 方法有什么区别

append表示把某个数据当做新元素整体追加到列表的最后面,它的参数可以是任意对象。

extend 的参数必须是一个可迭代对象,表示把该对象里面的所有元素逐个地追加到列表的后面。

In [1]: x = [1,2,3]In [2]: y = [4,5]In [3]: x.append(y)In [4]: x
Out[4]: [1, 2, 3, [4, 5]]In [5]: x = [1,2,3]In [6]: x.extend(y)In [7]: x
Out[7]: [1, 2, 3, 4, 5]

12. 深拷贝与浅拷贝

  • copy.copy 是浅拷贝,只会复制父对象,而不会复制对象内部的子对象;
  • copy.deepcopy 是深拷贝,会复制对象及其子对象;
In [1]: import copyIn [2]: a = [1,2,3, ['a', 'b']]In [3]: b = aIn [4]: c = a[:]In [5]: d = copy.copy(a)In [6]: e = copy.deepcopy(a)In [7]: id(a)
Out[7]: 62660040LIn [8]: id(b)
Out[8]: 62660040LIn [9]: id(c)
Out[9]: 62660424LIn [10]: id(d)
Out[10]: 62519944LIn [11]: id(e)
Out[11]: 62520776L

通过 = 赋值,它的 id 是和 a 本身是一样的;

通过 [:] 切片赋值和 copy.copy() 赋值的 id 是一样的,它们都是浅拷贝;

通过 copy.deepcopy() 赋值的 id 是和其它都不一样,它是深拷贝;为啥叫做深拷贝,看下面。

In [12]: a[0] = 'aaa'In [13]: a[3].append('c')In [14]: a
Out[14]: ['aaa', 2, 3, ['a', 'b', 'c']]In [15]: b
Out[15]: ['aaa', 2, 3, ['a', 'b', 'c']]In [16]: c
Out[16]: [1, 2, 3, ['a', 'b', 'c']]In [17]: d
Out[17]: [1, 2, 3, ['a', 'b', 'c']]In [18]: e
Out[18]: [1, 2, 3, ['a', 'b']]

参考:

http://www.bugcode.cn/PythonQuestions.html

https://segmentfault.com/a/1190000006265256

http://www.cnblogs.com/wilber2013/p/5178620.html

http://python.jobbole.com/86525/

http://www.cnblogs.com/wilber2013/p/4645353.html

http://www.cnblogs.com/Vito2008/p/5044251.html

Python 精选笔试面试习题—类继承、方法对象、包管理、闭包、可变类型作为默认参数、列表引用、sort与sorted、 append 和 extend、深拷贝和浅拷贝相关推荐

  1. Python 精选笔试面试习题—sorted 与 sort 单例模式、统计字符个数Count、垃圾回收、lambda函数、静态方法、类方法、实例方法、分布式锁、

    1. 字典根据键从小到大排序? In[38]: dic = {"name": "Tom", "age": 30, "country ...

  2. python可变类型做默认参数

    python可变类型做默认参数 下面代码的输出结果是什么 def extendlist(val, list=[]):list.append(val)return listlist1 = extendl ...

  3. 国内笔试面试风格及准备方法

    第一节 国内笔试面试风格及准备方法 免费试听 分享面试经验,通过例题分析国内面试的风格及准备方法 1) C/C++部分: 2)实现 memcpy 函数 STL 中 vector 的实现原理 2)概率题 ...

  4. 汇总5大Python常用笔试面试真题,知己知彼方能百战不殆

    俗话说的好,打仗之前知晓敌方的军情越多,获胜的把握也会越大,知己知彼方能百战不殆嘛!换个角度来说,如今的面试不正是和古代打战一样嘛,知晓的越多,成功几率也就越大,小编今天就为大家汇总了5大Python ...

  5. python基础-列表排序sort和sorted

    [Python基础]列表排序sort和sorted 文章目录 [Python基础]列表排序sort和sorted 1. sort 2. sorted 3. 如何使用sort获得排序后的列表的副本呢? ...

  6. python 类继承方法_python类的继承、多继承及其常用魔术方法

    继承 一个类可以派生出一个子类,这个子类可以使用父类的属性及方法,也可以在父类的基础上添加自己的独特属性或方法.属性和方法的继承的顺序是先从自己开始,找不到再去找父类,父类没有再找父类的父类,其尽头就 ...

  7. python class object_【python系统学习13】类(class)与对象(object)

    目录: 类(class)和实例 类 整数.字符串.浮点数等,不同的数据类型就属于不同的类. 想想看当初学数据类型,我们用type验证数据类型后打印的结果 忘了就再来看看: strs = '字符串' i ...

  8. Python学习之路:列表(List)的append()、extend()与insert()方法

    相同点 这三种方法的作用都是为列表(List)添加值 它们的语法为: list.append(obj)list.extend(seq)list.insert(index,obj) #此处index为对 ...

  9. Python当中的a += a 与 a = a + a 的区别,可变类型与不可变类型的数据类型,引用传参...

    a += a 与 a = a + a 的区别 可变类型a = a + a 的示例 In [58]: a = [11,22]In [59]: id(a) Out[59]: 140702917607688 ...

最新文章

  1. 查看并修改mysql的默认引擎
  2. 没了解过条件注解@ConditionalOn..?Spring Boot白学了!
  3. AlexNet原文解读+colab上运行caffe+caffe神经网络可视化(没有完成)
  4. 家用、商用、工业交换机的用途与区别
  5. MySQL介绍及安装(一)
  6. C++11 并发指南------std::thread 详解
  7. 简单的11步在Laravel中实现测试驱动开发
  8. 重写 geturl Openlayers中使用TileCache加载预切割图片作为基础地图图层
  9. 管理感悟:你说负责,关键在于怎样负责?
  10. plc编程软件通过计算机,英威腾PLC编程软件(Auto Station)
  11. 产品配件类目税目分类_商品和服务税收分类编码表
  12. 软件工程参考文献精品文献汇总
  13. 两万常用汉字的拼音+首字母缩写+unicode编码对照表
  14. 北京交通大学计算机仿真大作业直流调速系统仿真,计算机仿真技术大作业 12脉波整流电路仿真.doc...
  15. 【图像重建】基于Split Bregman实现稀疏图像重建附matlab代码
  16. 超全,整理了18种常用数据分析模型和方法
  17. 纯CSS实现图片百叶窗展示效果
  18. 用力一瞥Android渲染机制-黄油计划
  19. jQuery雪花插件JQuery-Snowfall Plugin
  20. 【礼堂椅安装】礼堂椅影院椅组装步骤方法

热门文章

  1. 2022-2028年中国微型汽车市场投资分析及前景预测报告
  2. 2022-2028年中国分离膜外壳行业市场调查研究及投资前景预测报告
  3. Git 常用操作(3)- 本地分之显示、创建、切换、合并和删除操作
  4. python实现二叉树的重建2 之由中序遍历和后序遍历重建
  5. Jquery实现form表单回填数据
  6. tf.nn.embedding_lookup()的用法
  7. Centos7上安装docker 详细教程
  8. Springboot前后端分离上传、下载压缩包、查看文件
  9. 操作系统学习笔记 第五章:文件管理(王道考研)
  10. SLAM架构的两篇顶会论文解析