基于Python自制視覺(jué)桌上冰球小游戲
介紹
大家好,今天和各位分享一下如何使用 mediapipe+opencv 制作桌上冰球的交互式小游戲。先放張圖看效果。
規(guī)則如下:左手控制白色球拍;右手控制紫色球拍;球拍只能上下移動(dòng);紅色圓形就是冰球;球碰撞到上下兩側(cè)的藍(lán)色邊框,和兩側(cè)的球拍就會(huì)反彈;如果球進(jìn)入了黃色區(qū)域,游戲結(jié)束;下面的粉色計(jì)數(shù)板,記錄左右兩側(cè)各擊球多少次。

1. 文件配置
1.1 導(dǎo)入工具包
pip install opencv_python==4.2.0.34 # 安裝opencv pip install mediapipe # 安裝mediapipe # pip install mediapipe --user #有user報(bào)錯(cuò)的話試試這個(gè) pip install cvzone # 安裝cvzone # 導(dǎo)入工具包 import cv2 import cvzone from cvzone.HandTrackingModule import HandDetector # 導(dǎo)入手部檢測(cè)模塊
21個(gè)手部關(guān)鍵點(diǎn)坐標(biāo)如下:

1.2 素材圖片準(zhǔn)備
開始之前,先準(zhǔn)備球桌的圖片,球的圖片,球拍的圖片。我是用PPT畫的圖,球和球拍的圖片一定要保存成 .png 格式的。放在同一個(gè)文件夾中以備讀取。

2. 手部關(guān)鍵點(diǎn)檢測(cè)、素材導(dǎo)入
2.1 方法介紹
(1)cvzone.HandTrackingModule.HandDetector()手部關(guān)鍵點(diǎn)檢測(cè)方法
參數(shù):
mode: 默認(rèn)為 False,將輸入圖像視為視頻流。它將嘗試在第一個(gè)輸入圖像中檢測(cè)手,并在成功檢測(cè)后進(jìn)一步定位手的坐標(biāo)。在隨后的圖像中,一旦檢測(cè)到所有 maxHands 手并定位了相應(yīng)的手的坐標(biāo),它就會(huì)跟蹤這些坐標(biāo),而不會(huì)調(diào)用另一個(gè)檢測(cè),直到它失去對(duì)任何一只手的跟蹤。這減少了延遲,非常適合處理視頻幀。如果設(shè)置為 True,則在每個(gè)輸入圖像上運(yùn)行手部檢測(cè),用于處理一批靜態(tài)的、可能不相關(guān)的圖像。
maxHands: 最多檢測(cè)幾只手,默認(rèn)為 2
detectionCon: 手部檢測(cè)模型的最小置信值(0-1之間),超過(guò)閾值則檢測(cè)成功。默認(rèn)為 0.5
minTrackingCon: 坐標(biāo)跟蹤模型的最小置信值 (0-1之間),用于將手部坐標(biāo)視為成功跟蹤,不成功則在下一個(gè)輸入圖像上自動(dòng)調(diào)用手部檢測(cè)。將其設(shè)置為更高的值可以提高解決方案的穩(wěn)健性,但代價(jià)是更高的延遲。如果 mode 為 True,則忽略這個(gè)參數(shù),手部檢測(cè)將在每個(gè)圖像上運(yùn)行。默認(rèn)為 0.5
它的參數(shù)和返回值類似于官方函數(shù) mediapipe.solutions.hands.Hands()
MULTI_HAND_LANDMARKS: 被檢測(cè)/跟蹤的手的集合,其中每只手被表示為21個(gè)手部地標(biāo)的列表,每個(gè)地標(biāo)由x, y, z組成。
MULTI_HANDEDNESS: 被檢測(cè)/追蹤的手是左手還是右手的集合。每只手由label(標(biāo)簽)和score(分?jǐn)?shù))組成。 label 是 'Left' 或 'Right' 值的字符串。 score 是預(yù)測(cè)左右手的估計(jì)概率。
(2)cvzone.HandTrackingModule.HandDetector.findHands() 找到手部關(guān)鍵點(diǎn)并繪圖
參數(shù):
img: 需要檢測(cè)關(guān)鍵點(diǎn)的幀圖像,格式為BGR
draw: 是否需要在原圖像上繪制關(guān)鍵點(diǎn)及識(shí)別框
flipType: 圖像是否需要翻轉(zhuǎn),當(dāng)視頻圖像和我們自己不是鏡像關(guān)系時(shí),設(shè)為True就可以了
返回值:
hands: 檢測(cè)到的手部信息,由0或1或2個(gè)字典組成的列表。如果檢測(cè)到兩只手就是由兩個(gè)字典組成的列表。字典中包含:21個(gè)關(guān)鍵點(diǎn)坐標(biāo)(x,y,z),檢測(cè)框左上坐標(biāo)及其寬高,檢測(cè)框中心點(diǎn)坐標(biāo),檢測(cè)出是哪一只手。
img: 返回繪制了關(guān)鍵點(diǎn)及連線后的圖像
(3)cv2.addWeighted()圖像融合
將兩張圖像按一定比例融合在一起,需要兩張圖像的size和通道數(shù)相同
兩張圖像按一定比例融合: cv2.addWeighted(圖像1, 權(quán)重1, 圖像2, 權(quán)重2, 亮度偏置)
相當(dāng)于 y = a x1 + b x2 + c,其中 a、b 代表權(quán)重,c 代表亮度上提亮多少
2.2 代碼展示
首先 cv2.imread() 中的參數(shù) cv2.IMREAD_UNCHANGED 是指用圖片的原來(lái)格式打開,包含Alpha通道。即以不改變圖片的方式打開,圖片是彩色那么讀進(jìn)來(lái)就是彩色,圖片是灰度圖那么讀進(jìn)來(lái)就是灰度圖,讀進(jìn)來(lái)的圖片的shape如下:

該部分代碼主要負(fù)責(zé)手部關(guān)鍵點(diǎn)檢測(cè),融合背景圖像和視頻幀圖像
import cv2
import cvzone
from cvzone.HandTrackingModule import HandDetector # 導(dǎo)入手部檢測(cè)模塊
#(1)捕獲攝像頭
cap = cv2.VideoCapture(0) # 0代表電腦自帶的攝像頭
cap.set(3, 1280) # 讀入的圖像的寬
cap.set(4, 720) # 讀入的圖像的高
#(2)文件配置
# 導(dǎo)入所有需要對(duì)圖片文件
imgDesk = cv2.imread('games/desk.jpg') # 球桌的圖片
imgBall = cv2.imread('games/ball.png', cv2.IMREAD_UNCHANGED) # 球的圖片
imgBlock1 = cv2.imread('games/block1', cv2.IMREAD_UNCHANGED) # 球拍的圖片
imgBlock2 = cv2.imread('games/block2', cv2.IMREAD_UNCHANGED) # 球拍的圖片
# 調(diào)整球桌圖片的size
imgDesk = cv2.resize(imgDesk, dsize=(1280,720))
#(3)參數(shù)設(shè)置
# 接收手部關(guān)鍵點(diǎn)識(shí)別的方法,最小手部檢測(cè)模塊置信度0.8,最多檢測(cè)2只手
detector = HandDetector(detectionCon=0.8, maxHands=2)
#(4)處理幀圖像
while True:
# 返回是否讀取成功,以及讀取后的幀圖像
success, img = cap.read() # 每次執(zhí)行讀取一幀
# 圖片翻轉(zhuǎn)呈鏡像關(guān)系,1代表左右翻轉(zhuǎn),0代表上下翻轉(zhuǎn)
img = cv2.flip(img, flipCode=1)
# 手部關(guān)鍵點(diǎn)檢測(cè),返回每個(gè)只手的信息和繪制后的圖像
hands, img = detector.findHands(img, flipType=False) # 上面翻轉(zhuǎn)過(guò)了這里就不用翻轉(zhuǎn)了
# 將球桌圖片和視頻幀圖像融合在一起, 兩張圖的shape要相同
# 給出每張圖片的融合權(quán)重, 亮度偏置為0,這樣就變成了半透明的顯示形式
img = cv2.addWeighted(img, 0.3, imgDesk, 0.7, 0)
#(5)添加桌球的圖片,將imgBall放在球桌img的指定坐標(biāo)位置
img = cvzone.overlayPNG(img, imgBall, (100,100))
# 圖像展示
cv2.imshow('img', img)
# 每幀滯留1ms后消失
k = cv2.waitKey(1)
# ESC鍵退出程序
if k & 0XFF==27:
break
# 釋放視頻資源
cap.release()
cv2.destroyAllWindows()效果圖如下:

3. 關(guān)鍵點(diǎn)處理、球拍移動(dòng)
3.1 方法介紹
這部分主要完成兩項(xiàng)工作,第一是左右手分別控制左側(cè)和右側(cè)的球拍,第二個(gè)是球以一定的速度移動(dòng)。
(1)控制球拍
hand['bbox'] 中包含了手部檢測(cè)框的左上角坐標(biāo)和檢測(cè)框的寬高,使用手掌中心點(diǎn)的 y 坐標(biāo)來(lái)控制球拍的上下移動(dòng)。由于兩個(gè)球拍的shape是相同的,因此只要獲取一個(gè)球拍的高度 h1 即可。使用掌心中點(diǎn) y 坐標(biāo)控制球拍中點(diǎn)的 y1 坐標(biāo),公式為:y1 = (y + h) // 2 - h1 // 2
接著使用 cvzone.overlayPNG() 就可以將球拍圖片覆蓋在原圖片的指定區(qū)域,其中坐標(biāo)參數(shù)是指覆蓋區(qū)域的左上角坐標(biāo)。固定橫坐標(biāo),只上下移動(dòng)。
(2)球移動(dòng)
首先要規(guī)定球的移動(dòng)速度 speedx, speedy = 10, 10 代表球每一幀沿x軸正方向移動(dòng)10個(gè)像素,沿y軸正方向移動(dòng)10個(gè)像素,那么球的初始合速度方向是沿圖片的正右下角移動(dòng)
如果球碰撞到了球桌的上下邊框,就反彈。speedy = -speedy。代表x方向每幀移動(dòng)的步長(zhǎng)不變,y方向每幀移動(dòng)的方向反轉(zhuǎn),即入射角等于出射角。
3.2 代碼展示
在上述代碼中補(bǔ)充
import cv2
import cvzone
import numpy as np
from cvzone.HandTrackingModule import HandDetector # 導(dǎo)入手部檢測(cè)模塊
#(1)捕獲攝像頭
cap = cv2.VideoCapture(0) # 0代表電腦自帶的攝像頭
cap.set(3, 1280) # 讀入的圖像的寬
cap.set(4, 720) # 讀入的圖像的高
#(2)文件配置
# 導(dǎo)入所有需要對(duì)圖片文件
imgDesk = cv2.imread('games/desk.jpg') # 球桌的圖片
imgBall = cv2.imread('games/ball.png', cv2.IMREAD_UNCHANGED) # 球的圖片
imgBlock1 = cv2.imread('games/block1.png', cv2.IMREAD_UNCHANGED) # 球拍的圖片
imgBlock2 = cv2.imread('games/block2.png', cv2.IMREAD_UNCHANGED) # 球拍的圖片
# 調(diào)整球桌圖片的size
imgDesk = cv2.resize(imgDesk, dsize=(1280,720))
# 調(diào)整球拍的size
imgBlock1 = cv2.resize(imgBlock1, dsize=(50,200))
imgBlock2 = cv2.resize(imgBlock2, dsize=(50,200))
#(3)參數(shù)設(shè)置
# 接收手部關(guān)鍵點(diǎn)識(shí)別的方法,最小手部檢測(cè)模塊置信度0.8,最多檢測(cè)2只手
detector = HandDetector(detectionCon=0.8, maxHands=2)
# 球的默認(rèn)位置
ballpos = [100, 100]
# 球的移動(dòng)速度,每幀15個(gè)像素
speedx, speedy = 10, 10
#(4)處理幀圖像
while True:
# 返回是否讀取成功,以及讀取后的幀圖像
success, img = cap.read() # 每次執(zhí)行讀取一幀
# 圖片翻轉(zhuǎn)呈鏡像關(guān)系,1代表左右翻轉(zhuǎn),0代表上下翻轉(zhuǎn)
img = cv2.flip(img, flipCode=1)
# 手部關(guān)鍵點(diǎn)檢測(cè),返回每個(gè)只手的信息和繪制后的圖像
hands, img = detector.findHands(img, flipType=False) # 上面翻轉(zhuǎn)過(guò)了這里就不用翻轉(zhuǎn)了
# 將球桌圖片和視頻幀圖像融合在一起, 兩張圖的shape要相同
# 給出每張圖片的融合權(quán)重, 亮度偏置為0,這樣就變成了半透明的顯示形式
img = cv2.addWeighted(img, 0.4, imgDesk, 0.6, 0)
#(5)處理手部關(guān)鍵點(diǎn),如果檢測(cè)到手了就進(jìn)行下一步
if hands:
# 遍歷每檢測(cè)的2只手,獲取每一只手的坐標(biāo)
for hand in hands:
# 獲取手部檢測(cè)框的左上坐標(biāo)xy,寬高wh
x, y, w, h = hand['bbox']
# 獲取球拍的寬高
h1, w1 = imgBlock1.shape[0:2]
# 球拍的中心y坐標(biāo),隨著掌心移動(dòng)
y1 = (y + h) // 2 - h1 // 2
# 如果檢測(cè)到了左手
if hand['type'] == 'Left':
# 左側(cè)的球拍x軸固定,y坐標(biāo)隨左手掌間中點(diǎn)移動(dòng)
img = cvzone.overlayPNG(img, imgBlock1, (55,y1))
# 如果檢測(cè)到了右手
if hand['type'] == 'Right':
# 右側(cè)的球拍x軸固定,y坐標(biāo)隨右手掌間中點(diǎn)移動(dòng)
img = cvzone.overlayPNG(img, imgBlock2, (1280-55,y1))
#(6)改變球的位置
# 如果球的y坐標(biāo)在超出了桌面的上或下邊框范圍,調(diào)整移動(dòng)方向
if ballpos[1] >= 600 or ballpos[1] <= 50:
# y方向的速度調(diào)整為反方向,那么x方向和y方向的合速度方向調(diào)整了
speedy = -speedy
ballpos[0] = ballpos[0] + speedx # 調(diào)整球的x坐標(biāo)
ballpos[1] = ballpos[1] + speedy # 調(diào)整球的y坐標(biāo)
#(5)添加桌球的圖片,將imgBall放在球桌img的指定坐標(biāo)位置
img = cvzone.overlayPNG(img, imgBall, ballpos)
# 圖像展示
cv2.imshow('img', img)
# 每幀滯留1ms后消失
k = cv2.waitKey(1)
# ESC鍵退出程序
if k & 0XFF==27:
break
# 釋放視頻資源
cap.release()
cv2.destroyAllWindows()效果圖如下:

4. 球拍擊球、游戲完善
4.1 方法介紹
這一部分主要完成三項(xiàng)工作,第一是球拍擊打到球,球需要反彈;第二是如果球進(jìn)入黃色區(qū)域,游戲結(jié)束;第三是左右側(cè)擊球得分計(jì)數(shù)器。
(1)球拍擊球
看到代碼中的第(5)步,ballpos 代表球的左上角坐標(biāo)(x,y),100 < ballpos[0] < 100+w1 代表球到了球拍橫坐標(biāo)區(qū)域范圍內(nèi)部了,y1 < ballpos[1] < y1+h1 代表球的y坐標(biāo)在球拍y坐標(biāo)內(nèi)部,這時(shí)表明擊球成功,speedx = -speedx 只改變沿x軸的速度方向,不改變沿y軸的速度方向。
(2)球進(jìn)黃區(qū),游戲結(jié)束
if ballpos[0] < 50 or ballpos[0] > 1150,如果球圖片的左上坐標(biāo)的 x 坐標(biāo),在黃區(qū)邊緣,整個(gè)程序退出。當(dāng)然也可以做一個(gè)游戲結(jié)束界面,我之前的博文里也有介紹,我偷個(gè)懶不寫了。
(3)計(jì)數(shù)器
首先定義個(gè)變量初始化記錄左右側(cè)的擊球次數(shù) score = [0, 0],如果有一側(cè)的球拍擊中球,那么對(duì)應(yīng)該側(cè)計(jì)數(shù)加一。
4.2 代碼展示
上面代碼是掌心控制球拍,這里改成食指指尖控制球拍中點(diǎn)移動(dòng)。
import cv2
import cvzone
from cvzone.HandTrackingModule import HandDetector # 導(dǎo)入手部檢測(cè)模塊
#(1)捕獲攝像頭
cap = cv2.VideoCapture(0) # 0代表電腦自帶的攝像頭
cap.set(3, 1280) # 讀入的圖像的寬
cap.set(4, 720) # 讀入的圖像的高
#(2)文件配置
# 導(dǎo)入所有需要對(duì)圖片文件
imgDesk = cv2.imread('games/desk.jpg') # 球桌的圖片
imgBall = cv2.imread('games/ball.png', cv2.IMREAD_UNCHANGED) # 球的圖片
imgBlock1 = cv2.imread('games/block1.png', cv2.IMREAD_UNCHANGED) # 球拍的圖片
imgBlock2 = cv2.imread('games/block2.png', cv2.IMREAD_UNCHANGED) # 球拍的圖片
# 調(diào)整球桌圖片的size
imgDesk = cv2.resize(imgDesk, dsize=(1280,720))
# 調(diào)整球拍的size
imgBlock1 = cv2.resize(imgBlock1, dsize=(50,200))
imgBlock2 = cv2.resize(imgBlock2, dsize=(50,200))
#(3)參數(shù)設(shè)置
# 接收手部關(guān)鍵點(diǎn)識(shí)別的方法,最小手部檢測(cè)模塊置信度0.8,最多檢測(cè)2只手
detector = HandDetector(detectionCon=0.8, maxHands=2)
# 球的默認(rèn)位置
ballpos = [100, 100]
# 球的移動(dòng)速度,每幀15個(gè)像素
speedx, speedy = 10, 10
# 記錄是否游戲結(jié)束
gameover = False
# 記錄左右的擊球數(shù)
score = [0, 0]
#(4)處理幀圖像
while True:
# 返回是否讀取成功,以及讀取后的幀圖像
success, img = cap.read() # 每次執(zhí)行讀取一幀
# 圖片翻轉(zhuǎn)呈鏡像關(guān)系,1代表左右翻轉(zhuǎn),0代表上下翻轉(zhuǎn)
img = cv2.flip(img, flipCode=1)
# 手部關(guān)鍵點(diǎn)檢測(cè),返回每個(gè)只手的信息和繪制后的圖像
hands, img = detector.findHands(img, flipType=False) # 上面翻轉(zhuǎn)過(guò)了這里就不用翻轉(zhuǎn)了
# 將球桌圖片和視頻幀圖像融合在一起, 兩張圖的shape要相同
# 給出每張圖片的融合權(quán)重, 亮度偏置為0,這樣就變成了半透明的顯示形式
img = cv2.addWeighted(img, 0.4, imgDesk, 0.6, 0)
#(5)處理手部關(guān)鍵點(diǎn),如果檢測(cè)到手了就進(jìn)行下一步
if hands:
# 遍歷每檢測(cè)的2只手,獲取每一只手的坐標(biāo)
for hand in hands:
# 獲取食指坐標(biāo)(x,y,z)
x, y, z = hand['lmList'][8]
# 獲取球拍的寬高
h1, w1 = imgBlock1.shape[0:2]
# 球拍的中心y坐標(biāo),隨著掌心移動(dòng)
y1 = y - h1 // 2
# 如果檢測(cè)到了左手
if hand['type'] == 'Left':
# 左側(cè)的球拍x軸固定,y坐標(biāo)隨左手掌間中點(diǎn)移動(dòng)
img = cvzone.overlayPNG(img, imgBlock1, (100,y1))
# 檢查球是否被左球拍擊中, 球的xy坐標(biāo)是否在球拍xy坐標(biāo)附近
if 100 < ballpos[0] < 100+w1 and y1 < ballpos[1] < y1+h1:
# 滿足條件代表球拍擊中了,改變球的移動(dòng)方向
speedx = -speedx # x方向設(shè)為反方向
# 得分加一
score[0] += 1
# 如果檢測(cè)到了右手
if hand['type'] == 'Right':
# 右側(cè)的球拍x軸固定,y坐標(biāo)隨右手掌間中點(diǎn)移動(dòng)
img = cvzone.overlayPNG(img, imgBlock2, (1150,y1))
# 檢查球是否被右球拍擊中
if 1050 < ballpos[0] < 1050+w1 and y1 < ballpos[1] < y1+h1:
# 滿足條件代表球拍擊中了,改變球的移動(dòng)方向
speedx = -speedx # x方向設(shè)為反方向
# 得分加一
score[1] += 1
#(6)檢查球是否沒(méi)接到,那么游戲結(jié)束
if ballpos[0] < 50 or ballpos[0] > 1150:
gameover = True
# 游戲結(jié)束,畫面就不動(dòng)了
if gameover is True:
break
# 游戲沒(méi)結(jié)束就接下去執(zhí)行
else:
#(7)調(diào)整球的坐標(biāo)
# 如果球的y坐標(biāo)在超出了桌面的上或下邊框范圍,調(diào)整移動(dòng)方向
if ballpos[1] >= 600 or ballpos[1] <= 50:
# y方向的速度調(diào)整為反方向,那么x方向和y方向的合速度方向調(diào)整了
speedy = -speedy
# 每一整都調(diào)整xy坐標(biāo)
ballpos[0] = ballpos[0] + speedx # 調(diào)整球的x坐標(biāo)
ballpos[1] = ballpos[1] + speedy # 調(diào)整球的y坐標(biāo)
#(8)添加桌球的圖片,將imgBall放在球桌img的指定坐標(biāo)位置
img = cvzone.overlayPNG(img, imgBall, ballpos)
#(9)顯示記分板
cvzone.putTextRect(img, f'Left:{score[0]} and Right:{score[1]}', (400,710))
#(10)圖像展示
cv2.imshow('img', img)
# 每幀滯留1ms后消失
k = cv2.waitKey(1)
# ESC鍵退出程序
if k & 0XFF==27:
break
# 釋放視頻資源
cap.release()
cv2.destroyAllWindows()效果圖如下:

到此這篇關(guān)于基于Python自制視覺(jué)桌上冰球小游戲的文章就介紹到這了,更多相關(guān)Python桌上冰球游戲內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python 讀取yaml文件的兩種方法(在unittest中使用)
這篇文章主要介紹了python 讀取yaml文件的兩種方法(在unittest中使用),幫助大家更好的理解和學(xué)習(xí)python,感興趣的朋友可以了解下2020-12-12
tensorflow實(shí)現(xiàn)訓(xùn)練變量checkpoint的保存與讀取
今天小編就為大家分享一篇tensorflow實(shí)現(xiàn)訓(xùn)練變量checkpoint的保存與讀取,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-02-02
Python filter()及reduce()函數(shù)使用方法解析
這篇文章主要介紹了Python filter()及reduce()函數(shù)使用方法解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09
Matplotlib實(shí)現(xiàn)各種條形圖繪制
這篇文章主要介紹了Matplotlib實(shí)現(xiàn)各種條形圖繪制,文章通過(guò)利用 plt.bar 方法實(shí)現(xiàn)各種條形圖繪制,內(nèi)容詳細(xì)具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-03-03
python如何使用requests提交post請(qǐng)求并上傳文件(multipart/form-data)
這篇文章主要給大家介紹了關(guān)于python如何使用requests提交post請(qǐng)求并上傳文件(multipart/form-data)的相關(guān)資料,Python有許多庫(kù)支持,它們可以簡(jiǎn)化HTTP上的數(shù)據(jù)傳輸,requests庫(kù)是最受歡迎的Python包之一,因?yàn)樗诰W(wǎng)絡(luò)刮削中被大量使用,需要的朋友可以參考下2023-11-11
Spark處理數(shù)據(jù)排序問(wèn)題如何避免OOM
這篇文章主要介紹了Spark處理數(shù)據(jù)排序問(wèn)題如何避免OOM,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-05-05
Python超詳細(xì)講解內(nèi)存管理機(jī)制
本章主要介紹Pyhon的內(nèi)存管理,以Pyhon的計(jì)數(shù)機(jī)制作為引入,介紹Pyhon的內(nèi)存管理方式,感興趣的朋友來(lái)看看吧2022-06-06
如何在python中實(shí)現(xiàn)隨機(jī)選擇
這篇文章主要介紹了如何在python中實(shí)現(xiàn)隨機(jī)選擇,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-11-11

