python面試題

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 //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 //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 = //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 = "//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關鍵字。

參考

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

Tags: