Python面試基礎(chǔ)(一)

列表排序

list0 = [31, 24, 6, 3, 10, 19, 2]
list0.sort()  # 升序排列
list0.sort(reverse=True)  # 降序排列
print(list0)

反轉(zhuǎn)

如果是列表的話,可以直接用list.reverse()來(lái)實(shí)現(xiàn),其他可以考慮range(len(list), -1, -1)

Magic Method

多重繼承(菱形繼承)

理解兩個(gè)概念:
supper和mro(method resolution order)
super指的是 MRO 中的下一個(gè)類,而不是父類。 ## 這一點(diǎn)很重要

# -*- coding: utf-8 -*-

class A(object):
    def __init__(self):
        print('welcome class A')

class B(A):
    def __init__(self):
        print('welcome class B')
        super(B, self).__init__()

    def extral(self):
        print('welcome to extral B')

class C(A):
    def __init__(self):
        print('welcome class C')
        super(C, self).__init__()

    def extral(self):
        print('welcome to extral C')

class D(C, B):
    def __init__(self):
        super(D, self).__init__()

if __name__ == '__main__':
    # print(D.mro())
    class_a = A()
    class_b = B()
    class_c = C()
    class_D = D()
    class_D.extral()

輸出:
welcome class A
welcome class B
welcome class A
welcome class C
welcome class A
welcome class C
welcome class B
welcome class A
welcome to extral C

如果把C類中super那一行注釋掉,則輸出變成:
welcome class A
welcome class B
welcome class A
welcome class C
welcome class C
welcome to extral C

最后,對(duì)于在子類中調(diào)用父類方法,要么直接使用父類名來(lái)調(diào)用方法,要么在子類中用super,保持一致,最好不要混用。

python單例模式的實(shí)現(xiàn)

單例模式(Singleton Pattern)是一種常用的軟件設(shè)計(jì)模式,該模式的主要目的是確保某一個(gè)類只有一個(gè)實(shí)例存在。當(dāng)你希望在整個(gè)系統(tǒng)中,某個(gè)類只能出現(xiàn)一個(gè)實(shí)例時(shí),單例對(duì)象就能派上用場(chǎng)。

比如,某個(gè)服務(wù)器程序的配置信息存放在一個(gè)文件中,客戶端通過(guò)一個(gè) AppConfig 的類來(lái)讀取配置文件的信息。如果在程序運(yùn)行期間,有很多地方都需要使用配置文件的內(nèi)容,也就是說(shuō),很多地方都需要?jiǎng)?chuàng)建 AppConfig 對(duì)象的實(shí)例,這就導(dǎo)致系統(tǒng)中存在多個(gè) AppConfig 的實(shí)例對(duì)象,而這樣會(huì)嚴(yán)重浪費(fèi)內(nèi)存資源,尤其是在配置文件內(nèi)容很多的情況下。事實(shí)上,類似 AppConfig 這樣的類,我們希望在程序運(yùn)行期間只存在一個(gè)實(shí)例對(duì)象。

在 Python 中,我們可以用多種方法來(lái)實(shí)現(xiàn)單例模式:

  1. 使用模塊
  2. 使用 new
  3. 使用裝飾器(decorator)
  4. 使用元類(metaclass)

模塊

我們只需把相關(guān)的函數(shù)和數(shù)據(jù)定義在一個(gè)模塊中,就可以獲得一個(gè)單例對(duì)象了。

# my_singleton.py
class Singleton(object):
    def foo():
        pass

my_singleton = Singleton()

# 然后在其他模塊中調(diào)用直接采用如下格式
from my_singleton import my_singleton
my_singleton.foo()

new

class Singleton(object):
    _instance = None
    def __new__(cls, *args, **kw):
        if not cls._instance:
            cls._instance = super(Singleton, cls).__new__(cls, *args, **kw)  
        return cls._instance  

class MyClass(Singleton):  
    a = 1

裝飾器

from functools import wraps
def singleton(cls):
    instances = {}
    @wraps(cls)
    def getinstance(*args, **kw):
        if cls not in instances:
            instances[cls] = cls(*args, **kw)
        return instances[cls]
    return getinstance

@singleton
class MyClass(object):
    a = 1

metaclass

class Singleton(type):
    _instances = {}
    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
        return cls._instances[cls]
# Python2
class MyClass(object):
    __metaclass__ = Singleton
# Python3
class MyClass(metaclass=Singleton):
    pass

copy.copy和copy.deepcopy

copy.copy: 只拷貝父對(duì)象,不會(huì)拷貝對(duì)象的內(nèi)部的子對(duì)象
copy.deepcopy: 拷貝對(duì)象及其子對(duì)象

a = [1,2,3,4,['a','b']]
b = copy.copy(a)
c = copy.deepcopy(a)
a.append(5)
a[4].append('c')
print(b)
print(c)

# 輸出
[1,2,3,4,['a','b','c']]
[1,2,3,4,['a','b']]

列表去重

# 方法一:轉(zhuǎn)集合再轉(zhuǎn)列表,會(huì)更改順序
org_list = [81, 24, 25, 8, 39, 24, 35, 35, 1, 8]
return list(set(org_list))

# 方法二:字典的fromkeys,會(huì)更改順序
org_list = [81, 24, 25, 8, 39, 24, 35, 35, 1, 8]
return {}.fromkeys(org_list).keys()  # python 2.x
# 如果是python 3.x版本,則換成return list({}.fromkeys(org_list).keys())

# 方法三:sort,保持順序
org_list = [81, 24, 25, 8, 39, 24, 35, 35, 1, 8]
new_list = list(set(org_list))
new_list.sort(key=org_list.index)
return new_list

# 方法四:函數(shù)和列表推導(dǎo),保持順序
org_list = [81, 24, 25, 8, 39, 24, 35, 35, 1, 8]
new_list = []
for value in org_list:
    if value not in new_list:
        new_list.append(value)
return new_list
# 有一種列表推導(dǎo)的方法跟這個(gè)類似
org_list = [81, 24, 25, 8, 39, 24, 35, 35, 1, 8]
new_list = []
[new_list.append(i) for i in org_list if i not in new_list]
return new_list

# 方法五:reduce,保持順序
org_list = [81, 24, 25, 8, 39, 24, 35, 35, 1, 8]
func = lambda x,y:x if y in x else x+[y]
return functools.reduce(func, [[]]+org_list)

append和extend的區(qū)別

append(object) —— object可以是str,list,dict等,把object作為一個(gè)整體追加在list的末尾
extend.(iterable) — 一個(gè)可迭代的對(duì)象,把這個(gè)對(duì)象的每個(gè)元素分別追加到list的末尾

org_list = ['welcome', 'to']
org_list.append(['my', 'home'])
print(org_list)  # ['welcome', 'to', ['my', 'home']]

org_list = ['welcome', 'to']
org_list.extend(['my', 'home'])
print(org_list)  # ['welcome', 'to', 'my', 'home']

global和nonlocal

global關(guān)鍵字用來(lái)在函數(shù)或其他局部作用域中使用全局變量。但是如果不修改全局變量也可以不使用global關(guān)鍵字

  1. 聲明全局變量,如果在局部要對(duì)全局變量修改,需要在局部也要先聲明該全局變量
# -*- coding: utf-8 -*-

gcount = 1

def global_test():
    global gcount
    gcount += 2
    print(gcount)

global_test()

上面的例子如果在函數(shù)不聲明全局變量,則會(huì)報(bào)錯(cuò)。

  1. 在局部如果不聲明全局變量,并且不修改全局變量。則可以正常使用全局變量
gcount = 0

def global_test():
    print(gcount)

global_test()

而nonlocal這個(gè)關(guān)鍵字是python3新引入的,之前如果要更改外部作用域里的變量,最簡(jiǎn)單的辦法就是將其放入全局作用域,用global關(guān)鍵字引入該變量。
現(xiàn)在只要在閉包內(nèi)用nonlocal聲明變量,就可以讓解釋器在外層函數(shù)中查找變量名了。

def a():
    x = 1
    def b():
        nonlocal x
        x += 1
        print(x)
    return b

a()()
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容