日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

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

發(fā)布時(shí)間:2023/11/27 生活经验 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python 精选笔试面试习题—类继承、方法对象、包管理、闭包、可变类型作为默认参数、列表引用、sort与sorted、 append 和 extend、深拷贝和浅拷贝 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

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()

如何才能調(diào)用類 A 的 show 方法呢?

obj.__class__ = A
obj.show()

__ class __ 方法指向了類對象,只用給他賦值類型 A,然后調(diào)用方法 show,但是用完了記得修改回來。

2. 方法對象

問題:為了讓下面這段代碼運(yùn)行,需要增加哪些代碼?

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)

答案:為了能讓對象實(shí)例能被直接調(diào)用,需要實(shí)現(xiàn)__ 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()

輸出結(jié)果:

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

使用__ new __ 方法,可以決定返回那個(gè)對象,也就是創(chuàng)建對象之前,這個(gè)可以用于設(shè)計(jì)模式的單例、工廠模式。__ init __ 是創(chuàng)建對象是調(diào)用的。

4. 默認(rèn)方法

如下代碼:

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 都沒有定義,怎樣修改代碼,使得沒有定義的方法都調(diào)用 mydefault 函數(shù),上面的代碼應(yīng)該輸出

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 __ 只有當(dāng)沒有定義的方法調(diào)用時(shí),才是調(diào)用他。當(dāng) fn1 方法傳入?yún)?shù)時(shí),我們可以給mydefault 方法增加一個(gè) *args 不定參數(shù)來兼容。

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)

輸出結(jié)果如下:

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

5. 包管理

一個(gè)包里有三個(gè)模塊,mod1.py, mod2.py, mod3.py,但使用 from demopack import * 導(dǎo)入模塊時(shí),如何保證只有 mod1、mod3 被導(dǎo)入了。

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

__all__ = ['mod1','mod3']

6. 閉包

寫一個(gè)函數(shù),接收整數(shù)參數(shù)n,返回一個(gè)函數(shù),函數(shù)的功能是把函數(shù)的參數(shù)和n相乘并把結(jié)果返回。

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

7. 可變類型作為函數(shù)默認(rèn)參數(shù)

下面代碼輸出結(jié)果是什么?

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

輸出結(jié)果為:

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

很多人都會(huì)誤認(rèn)為 list1=[10], list3=[‘a(chǎn)’],因?yàn)樗麄円詾槊看?extendList 被調(diào)用時(shí),列表參數(shù)的默認(rèn)值都將被設(shè)置為[].但實(shí)際上的情況是,新的默認(rèn)列表只在函數(shù)被定義的那一刻創(chuàng)建一次。當(dāng) extendList 被沒有指定特定參數(shù)list調(diào)用時(shí),這組list的值隨后將被使用。這是因?yàn)閹в心J(rèn)參數(shù)的表達(dá)式在函數(shù)被定義的時(shí)候被計(jì)算,不是在調(diào)用的時(shí)候被計(jì)算。
因此 list1 和 list3 是在同一個(gè)默認(rèn)列表上進(jìn)行操作(計(jì)算)的。而 list2 是在一個(gè)分離的列表上進(jìn)行操作(計(jì)算)的。(通過傳遞一個(gè)自有的空列表作為列表參數(shù)的數(shù)值)。

extendList 的定義可以作如下修改。盡管,創(chuàng)建一個(gè)新的列表,沒有特定的列表參數(shù)。

下面這段代碼可能能夠產(chǎn)生想要的結(jié)果。

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

通過上面的修改,輸出結(jié)果將變成:

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

8. 超出成員個(gè)數(shù)的切片

下面代碼輸出的結(jié)果是什么?

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

輸出結(jié)果為:

[]

例如,嘗試獲取list[10]和之后的成員,會(huì)導(dǎo)致 IndexError。
然而,嘗試獲取列表的切片,開始的index超過了成員個(gè)數(shù)不會(huì)產(chǎn)生 IndexError,而是僅僅返回一個(gè)空列表。
這成為特別讓人惡心的疑難雜癥,因?yàn)檫\(yùn)行的時(shí)候沒有錯(cuò)誤產(chǎn)生,導(dǎo)致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行的輸出結(jié)果如下:

[[], [], [], [], []]
[[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]

原因如下:

第一行的輸出結(jié)果直覺上很容易理解,例如 list = [ [ ] ] * 5 就是簡單的創(chuàng)造了5個(gè)空列表。
然而,理解表達(dá)式list=[ [ ] ] * 5的關(guān)鍵一點(diǎn)是它不是創(chuàng)造一個(gè)包含五個(gè)獨(dú)立列表的列表,而是它是一個(gè)創(chuàng)建了包含對同一個(gè)列表五次引用的列表。
只有了解了這一點(diǎn),我們才能更好的理解接下來的輸出結(jié)果。

list[0].append(10) 將10附加在第一個(gè)列表上。

但由于所有5個(gè)列表是引用的同一個(gè)列表,所以這個(gè)結(jié)果將是:

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

同理,list[1].append(20)將20附加在第二個(gè)列表上。但同樣由于5個(gè)列表是引用的同一個(gè)列表,所以輸出結(jié)果現(xiàn)在是:

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

作為對比, list.append(30)是將整個(gè)新的元素附加在外列表上,因此產(chǎn)生的結(jié)果是:

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

10. L.sort() 與 sorted() 的區(qū)別

L.sort(cmp=None, key=None, reverse=False)sorted(iterable, cmp=None, key=None, reverse=False)
  • L.sort():該函數(shù)的三個(gè)參數(shù)和 sorted() 的后三個(gè)參數(shù)含義是一致的,而需要特別注意的是,該函數(shù)只適用于列表,而非任意可以迭代的對象。cmp 是比較函數(shù),接受兩個(gè)對象參數(shù) x 和 y,返回 負(fù)數(shù)(x<y),0(x=y),正數(shù)(x>y)。
  • 該函數(shù)第一個(gè)參數(shù) iterable 為任意可以迭代的對象,cmp 是比較函數(shù),通常為lambda函數(shù),key 是用于比較的關(guān)鍵字,reverse表示排序結(jié)果是否反轉(zhuǎn)。
In [10]: aa = [5,4,3,2,1]In [11]: aa.sort()In [12]: aa
Out[12]: [1, 2, 3, 4, 5]

調(diào)用 sort() 之后會(huì)改變原來的表的結(jié)構(gòu)順序。

可以指定關(guān)鍵字排序

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

sorted() 可以應(yīng)用于任意的可以迭代的對象,所以應(yīng)用范圍比 L.sort() 廣泛的多,可以應(yīng)用于字符串,元組,列表,字典等可迭代對象。

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

需要注意的是,該函數(shù)會(huì)返回一個(gè)排序后的列表,原有可迭代對象保持不變,這與 L.sort() 函數(shù)不同。然而,這會(huì)浪費(fèi)較大的存儲(chǔ)空間,尤其是數(shù)據(jù)量較大時(shí)。所以,在列表進(jìn)行排序時(shí),需要考慮是否需要保存原列表,如果無需保存原列表,則優(yōu)先使用L.sort() 節(jié)省內(nèi)存空間,提高效率

  • L.sort() 函數(shù)只適用于列表排序,而sorted()函數(shù)適用于任意可以迭代的對象排序。
  • L.sort() 函數(shù)排序會(huì)改變原有的待排序列表,而sorted()函數(shù)則不會(huì)改變。所以在使用列表進(jìn)行排序時(shí),需要考慮是否需要保存原列表,如果無需保存原列表,則優(yōu)先使用L.sort() 節(jié)省內(nèi)存空間,提高效率。
  • 兩個(gè)函數(shù)通過定義 key 和 cmp 都可以完成排序,但是 key 的效率要遠(yuǎn)遠(yuǎn)高于 cmp,所以要優(yōu)先使用 key 。

11. append 與 extend 方法有什么區(qū)別

append表示把某個(gè)數(shù)據(jù)當(dāng)做新元素整體追加到列表的最后面,它的參數(shù)可以是任意對象。

extend 的參數(shù)必須是一個(gè)可迭代對象,表示把該對象里面的所有元素逐個(gè)地追加到列表的后面。

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 是淺拷貝,只會(huì)復(fù)制父對象,而不會(huì)復(fù)制對象內(nèi)部的子對象;
  • copy.deepcopy 是深拷貝,會(huì)復(fù)制對象及其子對象;
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

總結(jié)

以上是生活随笔為你收集整理的Python 精选笔试面试习题—类继承、方法对象、包管理、闭包、可变类型作为默认参数、列表引用、sort与sorted、 append 和 extend、深拷贝和浅拷贝的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。