python面試題

2022-07-28 06:01:15

python 基礎題

1.進位制間的轉換

進位制的轉換可以採用內建函數的方式進行資料的轉換,也可以使用int來轉換,是將所需轉換的數位按照某個進位制的規則進行轉換,最後轉換的結果均為int型別

number = 20

# 方式一
# 二進位制
print(bin(number))
# 八進位制
print(oct(number))
# 十六進位制
print(hex(number))
# 十進位制
print(int(number))

# 方式二,只能轉換為最後的int型別
# 將數位轉按照八進位制轉換為int型別
print(int(str(number), base=8))
# 將數位轉按照十六進位制轉換為int型別
print(int(str(number), base=16))
# 將0b二進位制字串按照二進位制轉換為int型別數位
print(int(str(bin(number)), base=2))

0b10100
0o24
0x14
20
16
32
20

需要注意的是,在python中,二進位制、八進位制、十六進位制在輸出顯示時都會以十進位制進行顯示,但無需過多關注

b_number = 0b10100
print(b_number)
o_number = 0o24
print(o_number)
h_number = 0x14
print(h_number)
20
20
20

2.最大遞迴數

通過以下簡易的函數可以看出最大遞迴數

def recursion(n):
    print(n)
    n += 1
    recursion(n)


recursion(1)

受python版本不同,最大遞迴數也存在不同

python2.7: 1000, 在第1000次呼叫此函數時會出現異常
python3.6: 998, 在998次呼叫此函數時會出現異常

可以手動設定最大遞迴數的數量

import sys
sys.setrecursionlimit(1200)

目前發現,當全部設定最大遞迴數為1200時,python2.7會在1200次報錯,但python3.6會在1198次報錯,相較少2次,依次可推出,預設的最大遞迴數應該是1000(第一次函數呼叫也算進去的話)。

3.and、not、or運運算元優先順序

物件 返回結果 優先順序
not x if x is false,then True,else False 1
x and y if x is false,then x,else y 2
x or y if x is false,then y,else x 3
v1 = 1 or 3  # 1
v2 = 1 and 3 # 3
v3 = 0 and 2 and 1 # 0
v4 = 0 and 2 or 1 # 1
v5 = 0 and 2 or 1 or 4 # 1
v6 = 0 or False and 1 # False
1
3
0
1
1
False

需要注意的是在python中,0也是代表False

4.三元運運算元,三目運運算元

在python中不存在如下注釋的三元運運算元,但是由三目運運算元代替,可以將簡單的條件分支語句寫成一行,適用於需要將程式碼簡化的場景,且相比較多行分支效率快一點。

a = 10
# print(a > 2 ? a : 0)

print(a if a > 2 else 0)

5.python2與python3區別

1.python2 True、False可以作為一個變數,可以對其進行賦值及取值,python3則不可以, True、False作為關鍵字無法修改

True = 1
print(True)

False = 0
print(False)

python2

1
0

python3

    True = 1
    ^
SyntaxError: can't assign to keyword

2.python2預設使用ASCII編碼,對中文需要手動新增檔案頭註釋, python3則不需要

print('你好')

python2

  File "/home/ts/flask_study/interview/05python2和python3的區別.py", line 12
SyntaxError: Non-ASCII character '\xe4' in file /home/ts/flask_study/interview/05python2和python3的區別.py on line 12, but no encoding declared; see http://python.org/dev/peps/pep-0263/ for details

需在py檔案最上方新增如下注釋

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

python3:則沒有影響

你好

3.python2的range返回一個list,資源消耗較大,python3返回一個可迭代物件,資源消耗較小,可使用for迴圈進行結果的迭代輸出,python3的range取代了xrange。

data = range(10)
print(data)
print(type(data))

from typing import Iterable, Iterator, Generator
print(isinstance(data, Iterable))
print(isinstance(data, Iterator))
print(isinstance(data, Generator))

python2

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
<type 'list'>

python3

range(0, 10)
<class 'range'>
True
False
False

4.python3引入nonlocal關鍵字,方便內部函數讀取和修改外部函數的值,當內部函數讀取和修改外部函數的值時,則外部函數和內部函數形成了閉包

def outter():
    number = 10
    def inner():
        nonlocal number
        number += 1
        print(number)
    return inner


outter()()

python2

UnboundLocalError: local variable 'number' referenced before assignment

python3

11

5.xreadlines、readlines讀取檔案,python2存在xreadlines,返回的是檔案物件,資源消耗少,python3無xreadlines, python2、python3返回的readlines都是一個list, 建議可以直接迭代遍歷open獲得的物件

import os

file_path = os.path.join(os.path.dirname(__file__), "01進位制轉換.py")
print(file_path)
with open(str(file_path), mode="r") as f:
    print(f)
    print(type(f))
    # print(isinstance(f, Iterable))
    for line in f:
        print(line)
    # lines = f.xreadlines()
    lines = f.readlines()
    print(lines)
    print(type(lines))

更多待更新中

6.布林值為False的值

print(bool(0))
print(bool(None))
print(bool([]))
print(bool({}))
print(bool(""))
print(bool(0j))

7.字串、列表、元組、字典每個常用的5個方法?

字串

str_data = 'adminasdasd asdasd'
# 計算字串中的元素出現次數
print(str_data.count('a'))
# 全部轉為大寫
print(str_data.upper())
# 以什麼開頭,可以指定開始的位置
print(str_data.startswith('a'))
# 擷取字串,使用較多
print(str_data.split('a'))
# 只在字串首部將首字母大寫
print(str_data.capitalize())
# 在字串中的每個單詞首字母大寫
print(str_data.title())
# 字串居中 前後補空格
print(str_data.center(22))
# 字串前面補0
print(str_data.zfill(22))
5
ADMINASDASD ASDASD
True
['', 'dmin', 'sd', 'sd ', 'sd', 'sd']
Adminasdasd asdasd
Adminasdasd Asdasd
  adminasdasd asdasd  
0000adminasdasd asdasd

列表

list_data = [1,2,3,4, [5,6]]
# 新增元素
list_data.append(11)
print(list_data)
# 淺拷貝列表資料, 當修改其中的可變物件時,原有物件會發生改變
copy_list_data = list_data.copy()
print(copy_list_data)
copy_list_data[4].append(4)
print(list_data)
print(copy_list_data)
# 刪除對應值的元素
list_data.remove(3)
print(list_data)
# 統計某個元素出現的次數
print(list_data.count(1))
# 兩個列表合併
list_data.extend(copy_list_data)
print(list_data)
# 列表排序,元素需要是同型別, 預設是升序
# list_data.sort()
print(list_data)
# 在指定下標插入元素
list_data.insert(0, -1)
print(list_data)
# 刪除對應下標的元素
list_data.pop(4)
print(list_data)
[1, 2, 3, 4, [5, 6], 11]
[1, 2, 3, 4, [5, 6], 11]
[1, 2, 3, 4, [5, 6, 4], 11]
[1, 2, 3, 4, [5, 6, 4], 11]
[1, 2, 4, [5, 6, 4], 11]
1
[1, 2, 4, [5, 6, 4], 11, 1, 2, 3, 4, [5, 6, 4], 11]
[1, 2, 4, [5, 6, 4], 11, 1, 2, 3, 4, [5, 6, 4], 11]
[-1, 1, 2, 4, [5, 6, 4], 11, 1, 2, 3, 4, [5, 6, 4], 11]
[-1, 1, 2, 4, 11, 1, 2, 3, 4, [5, 6, 4], 11]

元組

tuple_data = (1,2,3,4,5,1,5)
# 統計元素出現的次數
print(tuple_data.count(1))
# 獲取某個下標的元素
print(tuple_data.index(1))
2
0

字典

dict_data = {"name":"tom", "age":10, "gender":"man"}
dict_data2 = {"city":"nanjing"}
# 獲取字典的所有keys
print(dict_data.keys())
# 獲取字典的所有values
print(dict_data.values())
# 獲取字典的所有鍵值對,元組形式展示
print(dict_data.items())
# 合併兩個字典
dict_data.update(dict_data2)
print(dict_data)
# 獲取字典中的元素,可以設定預設值
print(dict_data.get('name', None))
# 刪除字典中的元素
dict_data.pop('age')
print(dict_data)
# 生成新字典,取出字典的key, 設定預設的value值,預設value為None
print(dict_data.fromkeys(dict_data.copy(), "no data"))
# 刪除字典中的元素,預設刪除最後一個元素
dict_data.popitem()
print(dict_data)
# 獲取字典中元素的值,當對應key不存在時會主動設定對應的key及返回設定的值, 當key存在時,此函數與get使用一致
print(dict_data.setdefault('age', 10))
print(dict_data)
# 清空字典
dict_data.clear()
print(dict_data)
dict_keys(['name', 'age', 'gender'])
dict_values(['tom', 10, 'man'])
dict_items([('name', 'tom'), ('age', 10), ('gender', 'man')])
{'name': 'tom', 'age': 10, 'gender': 'man', 'city': 'nanjing'}
tom
{'name': 'tom', 'gender': 'man', 'city': 'nanjing'}
{'name': 'no data', 'gender': 'no data', 'city': 'no data'}
{'name': 'tom', 'gender': 'man'}
10
{'name': 'tom', 'gender': 'man', 'age': 10}
{}

8.lambda使用方法及使用場景

def sum(m,n):
    return m+n

print(sum(1,2))
sum2 = lambda m,n:m+n
print(sum2(1,2))

lambda主要是針對於函數進行簡化程式碼操作,但只能進行簡單程式碼的簡化,複雜程式碼不建議使用lambda,

使用場景

1.map、reduce、filter等進行序列處理時使用
l = list(range(1, 10))
data = map(lambda n:n*n, l)
print(list(data))

from functools import reduce
data = reduce(lambda m,n:m*n, l)
print(data)
[1, 4, 9, 16, 25, 36, 49, 64, 81]
362880
2.lambda與list相結合, 注意lambda只會記錄最後一次的狀態,不會記錄中間過程的狀態
l2 = [lambda:i for i in range(10)]
print(l2[0]())
print(l2[3]())
9
9

9.pass的作用

pass主要就是在程式碼實現過程中,暫時沒有想好怎麼實現的時候,一般在函數、方法中使用較多,避免因為函數或方法中沒有內容導致報錯

10.*arg和**kwarg作用

在函數或方法中, *args會將元素轉換為元組, **kwargs會將x=y類似的元素轉換為字典

def run(*args, **kwargs):
    print(args)
    print(kwargs)

run(1,2,a=1,b=2)
(1, 2)
{'a': 1, 'b': 2}

2. *作為解包

l1 = [1,2,3]
l2 = [4,5,6]

l = list(zip(l1, l2))
print(l)
print(*l)
print(list(zip(*l)))
[(1, 4), (2, 5), (3, 6)]
(1, 4) (2, 5) (3, 6)
[(1, 2, 3), (4, 5, 6)]

11. is和==的區別

is 不僅比較值也比較記憶體地址, == 只比較值

a = 1
b = 1
print(id(a))
print(id(b))
print(a == b)
print(a is b)

c = {"name":"mike", "age":13}
d = {"name":"mike", "age":13}
print(id(c))
print(id(d))
print(c == d)
print(c is d)
10914496
10914496
True
True
140187512042624
140187511976800
True
False

12.深拷貝與淺拷貝

淺拷貝:複製的是物件的參照

對於不可變型別(字串、布林值、元組、數值型別等)來說,修改複製後的資料不會影響到原始資料,對於可變型別(列表、字典、集合)來說,修改複製後的資料會影響到原有資料。
淺拷貝除了使用copy中的copy方法外,一般不可變型別都會自己攜帶copy方法。

import copy

data = [1, 2, 3, [4, 5, 6], {"name": "tom", "gender": "man"}]

copy_data = copy.copy(data)

copy_data.append(7)
print(data)
print(copy_data)
copy_data[3].append(8)
print(data)
print(copy_data)
copy_data[4]["city"] = "nanjing"
print(data)
print(copy_data)
[1, 2, 3, [4, 5, 6], {'name': 'tom', 'gender': 'man'}]
[1, 2, 3, [4, 5, 6], {'name': 'tom', 'gender': 'man'}, 7]
[1, 2, 3, [4, 5, 6, 8], {'name': 'tom', 'gender': 'man'}]
[1, 2, 3, [4, 5, 6, 8], {'name': 'tom', 'gender': 'man'}, 7]
[1, 2, 3, [4, 5, 6, 8], {'name': 'tom', 'gender': 'man', 'city': 'nanjing'}]
[1, 2, 3, [4, 5, 6, 8], {'name': 'tom', 'gender': 'man', 'city': 'nanjing'},

深拷貝:生成一個新物件,將原始資料的值重新拷貝一份

對於不可變型別資料或者可變型別資料,修改複製後的資料均不會影響到原始資料

import copy


data = [1, 2, 3, [4, 5, 6], {"name": "tom", "gender": "man"}]

copy_data = copy.deepcopy(data)

copy_data.append(7)
print(data)
print(copy_data)
copy_data[3].append(8)
print(data)
print(copy_data)
copy_data[4]["city"] = "nanjing"
print(data)
print(copy_data)

使用場景

1.在某些情況下,我們需要複製某個列表或者字典的資料時,就需要使用深拷貝,防止對原始資料造成影響

13.可變型別和不可變型別

在python中資料型別分為可變和不可變型別,下面就簡單介紹一下 id()是檢視記憶體地址的函數:

可變型別:當資料的值發生改變時,記憶體地址不會發生改變

例如列表、集合、字典等

list_data = [1, 2, 4]
print(id(list_data))
list_data.append(5)
print(id(list_data))

dict_data = {"name": "tome", "gender": "man"}
print(id(dict_data))
dict_data.setdefault("city", "nanjing")
print(id(dict_data))

set_data = {1, 2, 4}
print(id(set_data))
set_data.add(3)
print(id(set_data))
2275116072896
2275116072896
2275115992448
2275115992448
2275116213728
2275116213728

不可變型別:當資料的值發生改變時,記憶體地址會發生改變

例如字串、布林值、整型、浮點型、元組等

str_data = 1
print(id(str_data))
str_data = 2
print(id(str_data))

str_data = "a"
print(id(str_data))
str_data = "b"
print(id(str_data))

str_data = 1.0
print(id(str_data))
str_data = 2.0
print(id(str_data))

tuple_data = (1, 2, 3)
print(id(tuple_data))
tuple_data = (1, 2, 4)
print(id(tuple_data))
2109049864432
2109049864464
2109051267184
2109051030000
2109050903248
2109050903024
2109051248000
2109051248256

14.Python垃圾回收機制?

15.求以下程式碼的結果

t = []
v = dict.fromkeys(["k1", "k2"], t)
print(v)
v["k1"].append(666)
print(v)
v["k1"] = 777
print(v)

由以下結果可以看出,在fromkeys生成字典的時候,設定的預設值指向的是同一個元素,相當於是淺拷貝了預設值

{'k1': [], 'k2': []}
{'k1': [666], 'k2': [666]}
{'k1': 777, 'k2': [666]}
def num():
    return [lambda x: i * x for i in range(4)]


print(num())
print([m(2) for m in num()])

由以下結果可以看出,lambda,不會記錄中間的狀態,只會記錄最後的狀態

[<function num.<locals>.<listcomp>.<lambda> at 0x0000026926836170>, <function num.<locals>.<listcomp>.<lambda> at 0x0000026926836200>, <function num.<locals>.<listcomp>.<lambda> at 0x0000026926836290>, <function num.<locals>.<listcomp>.<lambda> at 0x0000026926836320>]
[6, 6, 6, 6]

16.常見的內建函數及作用

map:將函數批次作用一個序列中

from typing import Iterator


list_data = [1, 2, 3]
data = map(lambda n: n * 2, list_data)
print(data)
print(type(data))
print(isinstance(data, Iterator))
for item in data:
    print(item)

由此可見,map物件是一個迭代器,可以被for迴圈或者next進行元素遍歷或者迭代

<map object at 0x0000026C4B6EBD90>
<class 'map'>
True
2
4
6

reduce:依次對序列進行函數處理並進行累計處理

from functools import reduce


list_data = [1, 2, 3]
data = reduce(lambda m, n: m * n, list_data)
print(data)

由此可見,返回的元素由函數最終的函數結果決定

6

filter:依據函數對序列進行過濾,返回符合條件的filter物件

from typing import Iterable


list_data = [1, 2, 3]
data = filter(lambda n: n > 2, list_data)
print(data)
print(type(data))
print(isinstance(data, Iterable))
for item in data:
    print(item)

由此可見,filter物件也是一個迭代器

<filter object at 0x000002045EA3BD90>
<class 'filter'>
True
3

sorted:自定義排序

sorted(Iterable, key, reverse=False)
key為需要進行排關鍵字
reverse預設為False、升序;反之則降序

dict_data = {"a": 1, "c": 3, "b": 2}
print(tuple(dict_data.items()))
# 按照字典的key排序
data = sorted(dict_data.items(), key=lambda x: x[0])
print(dict(data))
# 按照字典的value排序
data = sorted(dict_data.items(), key=lambda x: x[1], reverse=True)
print(dict(data))
(('a', 1), ('c', 3), ('b', 2))
{'a': 1, 'b': 2, 'c': 3}
{'c': 3, 'b': 2, 'a': 1}

17.一行程式碼實現9 * 9乘法表

18.python如何安裝第三方模組

pip 查詢模組

由於pip search module已經被python官方禁用,需要使用pip_search去搜尋相應模組,需要安裝pip-search模組,直接安裝即可,命令如下

pip install pip-search

搜尋模組,會顯示所有包含關鍵字的模組

pip_search module

pip 安裝模組

基本安裝方法
pip install module
一般國內預設的源較慢,可以指定安裝的源, 例如清華源、豆瓣源等,可以上網查詢
pip install module -r https://pypi.tuna.tsinghua.edu.cn/simple

使用上述命令可以使用安裝模組速度的加快,但是每次都需要額外新增源較為繁瑣,因此可以採用下面組態檔的方式,方便後續安裝模組。
1.在window的檔案管理器輸入%APPDATA%進入預設的使用者目錄,一般為C:\Users\xxx\AppData\Roaming, xxx為使用者名稱
2.在此資料夾下新建一個名為pip的資料夾
3.在新建的pip資料夾下建立一個名為pip.ini的檔案,此處使用的是清華源,也有一些其他的國內源,自行修改即可
內容如下:

[global]
timeout = 6000
index-url = https://pypi.tuna.tsinghua.edu.cn/simple
trusted-host = pypi.tuna.tsinghua.edu.cn

Linux與Windows類似,不同是路徑、檔案不一致,開啟檔案後直接將上述檔案寫入即可

mkdir ~/.pip
cd ~/.pip
touch pip.conf
vim pip.conf

內容輸入完後儲存即可,下載pip安裝的時候便會使用你設定的國內源,加快下載速度

有時候我們需要指定某個某個模組的版本

pip install module==1.0.1

匯出專案中使用的模組,方便移植

pip freeze > requirements.txt

既然有匯出,肯定有匯入

pip install -r requirements.txt

19.使用過的第三方模組,常用的模組?

第三方模組:即需要pip install安裝的模組
下面羅列一些可能會經常使用到的模組

  • os:操作檔案、資料夾路徑、系統分隔符等:詳細介紹:os相關操作
  • shutils:批次新建檔案、資料夾、壓縮檔案等,詳細介紹:shutils相關操作
  • request:請求操作,例如get、post等
    需要注意的是可能會出現get返回的資料為空的情況,是因為大部分網站都做了反扒處理,需要新增headers
    如下是requests的簡單使用
import requests

url = "https://movie.douban.com/"
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) \
        AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36"
}
response = requests.get(url, headers=headers)
result = pathlib.Path(__file__).parent.joinpath("douban.html")
with open(result, mode="w", encoding="utf8") as f:
    print(response.text)
    f.write(response.text)
    print(response)
  • virtualenv:建立虛擬環境
  • winreg:Windows登入檔相關
  • psutil:系統cpu、記憶體、執行緒相關
  • fire:新增命令列相關引數(main create ...)
  • flask:flas web框架
  • pyinstaller:將py檔案打包成exe檔案
  • configparser:操作ini檔案。詳細介紹:ini檔案操作
  • PyYAML:操作yaml檔案。詳細介紹:yaml檔案操作
  • 操作excel檔案:excel檔案操作
  • 操作xml、html的模組,lxml:詳細介紹: lxml相關操作
  • 持續更新中

20.re的match和search區別?

21.什麼是正則的貪婪匹配?

22.求結果

print([i % 2 for i in range(10)]) 
# 生成的是一個列表:[0, 1, 0, 1, 0, 1, 0, 1, 0, 1]
print((i % 2 for i in range(10)))
# 生成的是一個生成器,需要手動next或者for迴圈遍歷
print(1 or 2)  # 1
print(1 and 2)  # 2
print(1 < (2 == 2))  # False
print(1 < 2 == 2) # True

or: 第一個元素為True則輸出第一個元素, 反之
and: 第一個元素為Flase輸出第一個元素,反之
優先順序問題: 數位除了0為False其餘均為True

23.def func(a,b=[]) 這種寫法有什麼坑?

def func(a, b=[]):
    b.append(a)
    print(b)


for i in range(10):
    func(i)
[0]
[0, 1]
[0, 1, 2]
[0, 1, 2, 3]      
[0, 1, 2, 3, 4]   
[0, 1, 2, 3, 4, 5]
[0, 1, 2, 3, 4, 5, 6]
[0, 1, 2, 3, 4, 5, 6, 7]
[0, 1, 2, 3, 4, 5, 6, 7, 8]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

從上述結果發現,每次輸出都是疊加的,由此可見,b指向了[]的記憶體參照,類似於可變物件一樣,因此在函數或者方法中存在著一條規定:

預設引數必須要指向不可變物件

此處可以修改如下:

def func(a, b=None):
    if b is None:
        b = []
    b.append(a)
    print(b)


for i in range(10):
    func(i)

[0]
[1]
[2]
[3]
[4]
[5]
[6]
[7]
[8]
[9]

24.如何實現 「1,2,3」 變成 [‘1’,’2’,’3’] \ [‘1’,’2’,’3’]變成[1,2,3] ??

data = "1,2,3"
print(data.split(','))

data = ["1", "2", "3"]
print([int(n) for n in data])
print(list(map(lambda n: int(n), data)))

25.比較: a = [1,2,3] 和 b = [(1),(2),(3) ] 以及 b = [(1,),(2,),(3,) ] 的區別?

a = [1, 2, 3]
b = [(1), (2), (3)]
c = [(1,), (2,), (3,)]


print(type(a))
print(type(a[0]))
print(type(b))
print(type(b[0]))
print(type(c))
print(type(c[0]))
<class 'list'>
<class 'int'>  
<class 'list'> 
<class 'int'>  
<class 'list'> 
<class 'tuple'>

由此可見,a、b、c都是列表,不過其中的元素有所不同,a、b的元素都是int型別,c中的為元組

26.如何用一行程式碼生成[1,4,9,16,25,36,49,64,81,100] ?

使用map函數即可,map函數是對於序列中的元素進行批次操作

print(list(map(lambda n: n * n, range(1, 11))))

27.一行程式碼實現刪除列表中重複的值 ?

可以使用三種方式操作,如下

list_data = [1, 3, 4, 5, 6, 7, 2, 5, 1, 3, 8]

# 第一種方法,使用set, 預設會自動排序,順序可能會發生改變
print(list(set(list_data)))
# 第二種方法,遍歷列表元素去重


def remove_repeat(data):
    result_list = []
    for item in data:
        if list_data.count(item) == 1 or (
            list_data.count(item) > 1 and result_list.count(item) == 0
        ):
            result_list.append(item)
    return result_list

# 此方法使用yield 返回生成器的方式,節省消耗
def remove_repeat2(data):
    for item in data[-1:]:
        if list_data.count(item) == 1:
            yield item
        else:
            data.remove(item)


print(remove_repeat(list_data))
print(list(remove_repeat2(list_data)))

# 第三種方法,使用Counter
from collections import Counter

print(list(Counter(list_data)))

28.如何在函數中設定一個全域性變數 ?

一般在python中有兩種全域性變數,一種是函數中的全域性變數,還有一種是全域性的變數

全域性變數

此處函數中通過global獲取到全域性變數

count = 0


def run():
    global count
    count += 1


run()
print(count)
# 1

函數中的全域性變數

nonlocal是python3出現的,方便內部函數呼叫外部函數變數, 如果不使用nonlocal,只能獲取外部函數的變數值

def outter():
    number = 1

    def inner():
        nonlocal number
        number += 1
        print(number)
    return inner


outter()()
# 2

29.logging模組的作用?以及應用場景?

logging是python自帶的紀錄檔模組,可以很方便的進行紀錄檔的輸出及輸出到檔案等
主要分為如下幾個等級。

紀錄檔等級 描述
INFO 無異常時輸出的紀錄檔,主要是確認程式是否正常按照預期進行的
DEBUG 一般在開發階段使用,用於問題的診斷與定位
WARNING 當出現一些異常資訊(例如磁碟空間不足)時,但是不會影響程式的正常執行
ERROR 當出現問題時導致程式無法正常執行時
CRITICAL 當出現嚴重問題時導致程式無法繼續執行時
import logging


logging.info("info")
logging.warning("warning")
logging.debug("debug")
logging.error("error")
logging.critical("critical")

通常情況下,我們在專案中會定義一個紀錄檔類,方便將紀錄檔輸出的檔案中:詳細介紹:紀錄檔記錄類

30.請用程式碼簡答實現stack

31.常用字串格式化哪幾種?

已知三種, %\ f\ format

print("%d %s" % (1, "test"))

timeout = 1
print(f"{timeout}")
print("{}".format("test"))

32.簡述 生成器、迭代器、可迭代物件 以及應用場景?

詳細介紹:迭代器、生成器

33.用Python實現一個二分查詢的函數。

二分查詢

也稱折半查詢,意思是從有序的序列(n個元素)中找到一個元素,預設從中間(n/2)開始找, 在找的過程中會出現以下三種情況:

  • 需要找的元素大於中間元素,則到n/2右邊的序列中繼續進行二分查詢
  • 需要找的元素小於中間元素,則到n/2左邊的序列中繼續進行二分查詢
  • 需要找的元素剛好就是中間元素,查詢結束
target = 9
list_data = [1, 2, 4, 2, 9, 43, 2]
list_len = len(list_data)
index = 0
middle = int(list_len / 2) - 1
while True:
    if target == list_data[middle]:
        index = middle
        break
    elif target > list_data[middle]:
        middle = middle + int((list_len - middle) / 2) - 1
    else:
        middle = int(middle / 2) - 1

print(index)

34.談談你對閉包的理解?

閉包理解

35.os和sys模組的作用?

os和sys都屬於系統層級的模組
os:通常用於檔案、資料夾的相關操作(新建、刪除、重新命名等),也可用於路徑的獲取與切換;執行命令等
sys:通常用於命令列引數的獲取、系統平臺的獲取、系統執行路徑等

36.如何生成一個亂數?

import random


rand = random.Random()
# 隨機生成0-1內的浮點型別資料
print(rand.random())
# 生成0-1符合 貝塔分佈
print(rand.betavariate(0.1, 0.5))
tu = (1, 2, 3, 4, 78, 12, 98)
# 從一個非空序列中選擇一個元素
print(rand.choice(tu))
# 從列表中隨機選取多個值,返回的是一個列表
print(rand.choices(tu, k=2))
# 返回一個區間內的數位
print(rand.randint(1, 100))
# 返回一個區間的數位,不過可以指定step步長
print(rand.randrange(1, 100, 2))

37.如何使用python刪除一個檔案?

使用os中的刪除檔案或者資料夾,不過無法刪除裡面包含資料夾或者檔案的資料夾,需要遞迴進行操作

import os
import time


os.mkdir("test")
time.sleep(4)
os.rmdir("test")

with open("1.txt", mode="w", encoding="utf8") as f:
    f.write("test" * 10)
time.sleep(4)
os.remove("1.txt")

os.makedirs("test2/test3")
time.sleep(4)
os.removedirs("test2/test3")

使用shutil可以遞迴操作資料夾

import shutil

# 相當於mv
shutil.move()
# 拷貝整個資料夾,裡面可以包含子檔案或者子資料夾
shutil.copytree()
# 與上述類似,可以刪除整個資料夾,哪怕存在子資料夾
shutil.rmtree()

38.談談你對物件導向的理解?

詳細介紹: 物件導向理解

39.Python物件導向中的繼承有什麼特點?

詳細介紹: 物件導向理解

40.物件導向深度優先和廣度優先是什麼?

詳細介紹: 物件導向理解

41.物件導向中super的作用?

詳細介紹: 物件導向理解

42.是否使用過functools中的函數?其作用是什麼?

reduce:對序列進行疊加操作

from functools import reduce


li = [1, 2, 3, 4]
print(reduce(lambda m, n: m + n, li))

wraps:裝飾器中的改變函數註釋及函數名稱的

from functools import wraps


def decorator(func):
    @wraps(func)
    def inner(*args, **kwargs):
        func(*args, **kwargs)

    return inner

partial:偏函數,用於生成新函數,可以指定某些固定的引數

from functools import partial


def fun(x, y, z):
    return x + y + z


fun2 = partial(fun, 1)
print(fun2(2, 4))

43.列舉物件導向中帶爽下劃線的特殊方法

詳細可以檢視常見魔法函數

44.如何判斷是函數還是方法?

廣義來說,在類中的繫結了範例變數的實體方法叫方法,非類中的叫函數
python有自帶的可以區分是函數還是方法的函數。

from abc import abstractmethod
import inspect


def fun():
    pass


print(inspect.isfunction(fun))
print(inspect.ismethod(fun))
print(type(fun))


class Test:
    def __init__(self) -> None:
        pass

    def fun():
        pass

    def fun2(self):
        pass

    @staticmethod
    def fun3():
        pass

    @classmethod
    def fun4(cls):
        pass

    @abstractmethod
    def fun5():
        pass


fun2 = Test().fun2
print(inspect.isfunction(fun2))
print(inspect.ismethod(fun2))
print(type(fun2))

fun = Test().fun
print(inspect.isfunction(fun))
print(inspect.ismethod(fun))
print(type(fun))

fun3 = Test().fun3
print(inspect.isfunction(fun3))
print(inspect.ismethod(fun3))
print(type(fun3))

fun4 = Test().fun4
print(inspect.isfunction(fun4))
print(inspect.ismethod(fun4))
print(type(fun4))

fun5 = Test().fun5
print(inspect.isfunction(fun5))
print(inspect.ismethod(fun5))
print(type(fun5))

True
False
<class 'function'>
False
True
<class 'method'>
False
True
<class 'method'>
True
False
<class 'function'>
False
True
<class 'method'>
False
True
<class 'method'>

由上述可見,類中的處理靜態方法是函數,其他的都是方法,非類中的都是函數。

45.靜態方法和類方法區別?

區別 靜態方法 類方法
修飾的方法 staticmethod classmethod
方法型別 函數 方法
是否獲取範例物件 不可以 不可以
傳入引數 可以傳入引數 必須要傳入cls後才能再傳入引數
呼叫方式 類呼叫,類物件呼叫都可以 類呼叫、類物件呼叫都可以
class Test:
    def __init__(self) -> None:
        self.name = "mike"
    
    @staticmethod
    def static_method(a, b):
        print(a + b)
        print("static_method")

    @classmethod
    def class_method(cls, a, b):
        print(a + b)
        print("class_method")


t = Test()
t.static_method(1, 2)
Test.static_method(2, 3)
t.class_method(1, 2)
Test.class_method(2, 3)

46.列舉物件導向中的特殊成員以及應用場景

常見的魔法函數

47.什麼是反射?以及應用場景?

詳細介紹:python 反射

48.metaclass作用?以及應用場景?

type與metaclass

49.用盡量多的方法實現單例模式。

50.裝飾器的寫法及應用場景?

詳細介紹:裝飾器

51.例外處理寫法以及如何主動跑出異常(應用場景)

例外處理

52.什麼是物件導向的mro

MRO的全稱是Method Resolution Order(方法解析順序),它指的是一棵類繼承樹,當呼叫最底層類物件的所對應的實體方法時, python直譯器在類繼承樹上的搜尋方法的順序。對於一棵類繼承樹可以通過最底層方法mro()或是__mro__的屬性獲得他的MRO。

class D:
    def run(self):
        print("d run")


class C(D):
    def run(self):
        print("C run")


class B(D):
    def run3(self):
        print("B run")


class A(B, C):
    def run2(self):
        print("A run")


A().run()
print(A.mro())

使用mro()可以得到一個類的繼承順序,一般在python3中預設時廣度優先。

53.isinstance作用以及應用場景?

官方說法:
如果 object 引數是 classinfo 引數的範例,或其(直接、間接或 virtual )子類的範例,則返回 True。 如果 object 不是給定型別的物件,則總是返回 False。如果 classinfo 是型別物件的元組(或由該類元組遞迴生成)或多個型別的 union 型別,那麼當 object 是其中任一型別的範例時就會返回 True。如果 classinfo 不是某個型別或型別元組,將會觸發 TypeError 異常。
通俗點說,判斷某個物件是否是某個型別。

print(isinstance("1", str))
print(isinstance("1", int))

print(isinstance(1, int))
print(isinstance(1, str))

print(isinstance([1, 2], list))
print(isinstance([1, 2], tuple))

54,給定一個整數陣列,返回兩個數位的索引,使它們相加到一個特定的目標。您可以假設每個輸入都會只有一個解決方案,您可能不會兩次使用相同的元素。

例如

Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,

return [0, 1]
nums = [2, 7, 11, 15, 34, 1, 23, 11]
target = 25


def fun(data, target):
    for index, item in enumerate(nums):
        if item > target:
            continue
        if data.count(target - item) > 0:
            return [index, data.index(target - item)]
    return False


print(fun(nums, target))

55.json序列化時,可以處理的資料型別有哪些?如何客製化支援datetime型別?

56.有用過with statement嗎?它的好處是什麼?

57.使用程式碼實現檢視列舉目錄下的所有檔案。

# 使用程式碼實現檢視列舉目錄下的所有檔案。
import os
import pathlib


dir_path = "D:\python_study"
# 資料夾名稱 資料夾下的資料夾,以列表形式呈現 資料夾下的檔案,以列表形式呈現
for dirpath, dir_list, file_list in os.walk(dir_path):
    print(f"dirpath:{dirpath}")
    print(f"dirnames:{dir_list}")
    print(f"filenames:{file_list}")


# 只能顯示當前層級的資料夾,以列表形式呈現
print(os.listdir(dir_path))

# 只能顯示當前層級的資料夾,以生成式+路徑物件形式呈現
print(list(pathlib.Path(dir_path).iterdir()))
print(list(pathlib.Path(dir_path).glob("*")))

# 顯示所有的檔案及資料夾 路徑物件,以生成器+路徑物件形式呈現
print(list(pathlib.Path(dir_path).rglob("*")))

58.簡述 yield和yield from關鍵字。

參考

作者:武沛齊
出處:http://www.cnblogs.com/wupeiqi/
本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連線。