欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python圖片存儲(chǔ)和訪問(wèn)的三種方式詳解

 更新時(shí)間:2022年04月06日 11:33:20   作者:Mr數(shù)據(jù)楊  
在?Python?中處理圖像數(shù)據(jù)的時(shí)候,例如應(yīng)用卷積神經(jīng)網(wǎng)絡(luò)等算法可以處理大量圖像數(shù)據(jù)集,這里就需要學(xué)習(xí)如何用最簡(jiǎn)單的方式存儲(chǔ)、讀取數(shù)據(jù)。本文介紹了Python中圖片存儲(chǔ)和訪問(wèn)的三種方式,需要的可以參考一下

前言

ImageNet 是一個(gè)著名的公共圖像數(shù)據(jù)庫(kù),用于訓(xùn)練對(duì)象分類、檢測(cè)和分割等任務(wù)的模型,它包含超過(guò) 1400 萬(wàn)張圖像。

在 Python 中處理圖像數(shù)據(jù)的時(shí)候,例如應(yīng)用卷積神經(jīng)網(wǎng)絡(luò)(也稱CNN)等算法可以處理大量圖像數(shù)據(jù)集,這里就需要學(xué)習(xí)如何用最簡(jiǎn)單的方式存儲(chǔ)、讀取數(shù)據(jù)。

對(duì)于圖像數(shù)據(jù)處理應(yīng)該有有個(gè)定量的比較方式,讀取和寫入文件需要多長(zhǎng)時(shí)間,以及將使用多少磁盤內(nèi)存。

分別用不同的方式去處理、解決圖像的存儲(chǔ)、性能優(yōu)化的問(wèn)題。

數(shù)據(jù)準(zhǔn)備

一個(gè)可以玩的數(shù)據(jù)集

我們熟知的圖像數(shù)據(jù)集 CIFAR-10,由 60000 個(gè) 32x32 像素的彩色圖像組成,這些圖像屬于不同的對(duì)象類別,例如狗、貓和飛機(jī)。相對(duì)而言 CIFAR 不是一個(gè)非常大的數(shù)據(jù)集,但如使用完整的 TinyImages 數(shù)據(jù)集,那么將需要大約 400GB 的可用磁盤空間。

文中的代碼應(yīng)用的數(shù)據(jù)集下載地址 CIFAR-10 數(shù)據(jù)集 。

這份數(shù)據(jù)是使用cPickle進(jìn)行了序列化和批量保存。pickle模塊可以序列化任何 Python 對(duì)象,而無(wú)需進(jìn)行任何額外的代碼或轉(zhuǎn)換。但是有一個(gè)潛在的嚴(yán)重缺點(diǎn),即在處理大量數(shù)據(jù)時(shí)會(huì)帶來(lái)安全風(fēng)險(xiǎn)無(wú)法評(píng)估。

圖像加載到 NumPy 數(shù)組中

import numpy as np
import pickle
from pathlib import Path

# 文件路徑
data_dir = Path("data/cifar-10-batches-py/")

# 解碼功能
def unpickle(file):
    with open(file, "rb") as fo:
        dict = pickle.load(fo, encoding="bytes")
    return dict

images, labels = [], []
for batch in data_dir.glob("data_batch_*"):
    batch_data = unpickle(batch)
    for i, flat_im in enumerate(batch_data[b"data"]):
        im_channels = []
        # 每個(gè)圖像都是扁平化的,通道按 R, G, B 的順序排列  
        for j in range(3):
            im_channels.append(
                flat_im[j * 1024 : (j + 1) * 1024].reshape((32, 32))
            )
        # 重建原始圖像
        images.append(np.dstack((im_channels)))
        # 保存標(biāo)簽
        labels.append(batch_data[b"labels"][i])

print("加載 CIFAR-10 訓(xùn)練集:")
print(f" - np.shape(images)     {np.shape(images)}")
print(f" - np.shape(labels)     {np.shape(labels)}")

圖像存儲(chǔ)的設(shè)置

安裝三方庫(kù) Pillow 用于圖像處理 。

pip install Pillow

LMDB

LMDB 也稱為“閃電數(shù)據(jù)庫(kù)”,代表閃電內(nèi)存映射數(shù)據(jù)庫(kù),因?yàn)樗俣瓤觳⑶沂褂脙?nèi)存映射文件。它是鍵值存儲(chǔ),而不是關(guān)系數(shù)據(jù)庫(kù)。

安裝三方庫(kù) lmdb 用于圖像處理 。

pip install lmdb

HDF5

HDF5 代表 Hierarchical Data Format,一種稱為 HDF4 或 HDF5 的文件格式。起源于美國(guó)國(guó)家超級(jí)計(jì)算應(yīng)用中心,是一種可移植、緊湊的科學(xué)數(shù)據(jù)格式。

安裝三方庫(kù) h5py 用于圖像處理 。

pip install h5py

單一圖像的存儲(chǔ)

3種不同的方式進(jìn)行數(shù)據(jù)讀取操作

from pathlib import Path

disk_dir = Path("data/disk/")
lmdb_dir = Path("data/lmdb/")
hdf5_dir = Path("data/hdf5/")

同時(shí)加載的數(shù)據(jù)可以創(chuàng)建文件夾分開(kāi)保存

disk_dir.mkdir(parents=True, exist_ok=True)
lmdb_dir.mkdir(parents=True, exist_ok=True)
hdf5_dir.mkdir(parents=True, exist_ok=True)

存儲(chǔ)到 磁盤

使用 Pillow 完成輸入是一個(gè)單一的圖像 image,在內(nèi)存中作為一個(gè) NumPy 數(shù)組,并且使用唯一的圖像 ID 對(duì)其進(jìn)行命名image_id。

單個(gè)圖像保存到磁盤

from PIL import Image
import csv

def store_single_disk(image, image_id, label):
    """ 將單個(gè)圖像作為 .png 文件存儲(chǔ)在磁盤上。
        參數(shù):
        ---------------
        image       圖像數(shù)組, (32, 32, 3) 格式
        image_id    圖像的整數(shù)唯一 ID
        label       圖像標(biāo)簽
    """
    Image.fromarray(image).save(disk_dir / f"{image_id}.png")

    with open(disk_dir / f"{image_id}.csv", "wt") as csvfile:
        writer = csv.writer(
            csvfile, delimiter=" ", quotechar="|", quoting=csv.QUOTE_MINIMAL
        )
        writer.writerow([label])

存儲(chǔ)到 LMDB

LMDB 是一個(gè)鍵值對(duì)存儲(chǔ)系統(tǒng),其中每個(gè)條目都保存為一個(gè)字節(jié)數(shù)組,鍵將是每個(gè)圖像的唯一標(biāo)識(shí)符,值將是圖像本身。

鍵和值都應(yīng)該是字符串。 常見(jiàn)的用法是將值序列化為字符串,然后在讀回時(shí)將其反序列化。

用于重建的圖像尺寸,某些數(shù)據(jù)集可能包含不同大小的圖像會(huì)使用到這個(gè)方法。

class CIFAR_Image:
    def __init__(self, image, label):
        self.channels = image.shape[2]
        self.size = image.shape[:2]

        self.image = image.tobytes()
        self.label = label

    def get_image(self):
        """ 將圖像作為 numpy 數(shù)組返回 """
        image = np.frombuffer(self.image, dtype=np.uint8)
        return image.reshape(*self.size, self.channels)

單個(gè)圖像保存到 LMDB

import lmdb
import pickle

def store_single_lmdb(image, image_id, label):
    """ 將單個(gè)圖像存儲(chǔ)到 LMDB
        參數(shù):
        ---------------
        image       圖像數(shù)組, (32, 32, 3) 格式
        image_id    圖像的整數(shù)唯一 ID
        label       圖像標(biāo)簽
    """
    map_size = image.nbytes * 10

    # Create a new LMDB environment
    env = lmdb.open(str(lmdb_dir / f"single_lmdb"), map_size=map_size)

    # Start a new write transaction
    with env.begin(write=True) as txn:
        # All key-value pairs need to be strings
        value = CIFAR_Image(image, label)
        key = f"{image_id:08}"
        txn.put(key.encode("ascii"), pickle.dumps(value))
    env.close()

存儲(chǔ) HDF5

一個(gè) HDF5 文件可以包含多個(gè)數(shù)據(jù)集??梢詣?chuàng)建兩個(gè)數(shù)據(jù)集,一個(gè)用于圖像,一個(gè)用于元數(shù)據(jù)。

import h5py

def store_single_hdf5(image, image_id, label):
    """ 將單個(gè)圖像存儲(chǔ)到 HDF5 文件
        參數(shù):
        ---------------
        image       圖像數(shù)組, (32, 32, 3) 格式
        image_id    圖像的整數(shù)唯一 ID
        label       圖像標(biāo)簽
    """
    # 創(chuàng)建一個(gè)新的 HDF5 文件
    file = h5py.File(hdf5_dir / f"{image_id}.h5", "w")

    # 在文件中創(chuàng)建數(shù)據(jù)集
    dataset = file.create_dataset(
        "image", np.shape(image), h5py.h5t.STD_U8BE, data=image
    )
    meta_set = file.create_dataset(
        "meta", np.shape(label), h5py.h5t.STD_U8BE, data=label
    )
    file.close()

存儲(chǔ)方式對(duì)比

將保存單個(gè)圖像的所有三個(gè)函數(shù)放入字典中。

_store_single_funcs = dict(
    disk=store_single_disk, 
    lmdb=store_single_lmdb, 
    hdf5=store_single_hdf5
)

以三種不同的方式存儲(chǔ)保存 CIFAR 中的第一張圖像及其對(duì)應(yīng)的標(biāo)簽。

from timeit import timeit

store_single_timings = dict()

for method in ("disk", "lmdb", "hdf5"):
    t = timeit(
        "_store_single_funcs[method](image, 0, label)",
        setup="image=images[0]; label=labels[0]",
        number=1,
        globals=globals(),
    )
    store_single_timings[method] = t
    print(f"存儲(chǔ)方法: {method}, 使用耗時(shí): {t}")

來(lái)一個(gè)表格看看對(duì)比。

存儲(chǔ)方法存儲(chǔ)耗時(shí)使用內(nèi)存
Disk2.1 ms8 K
LMDB1.7 ms32 K
HDF58.1 ms8 K

多個(gè)圖像的存儲(chǔ)

同單個(gè)圖像存儲(chǔ)方法類似,修改代碼進(jìn)行多個(gè)圖像數(shù)據(jù)的存儲(chǔ)。

多圖像調(diào)整代碼

將多個(gè)圖像保存為.png文件就可以理解為多次調(diào)用 store_single_method() 這樣。但這不適用于 LMDB 或 HDF5,因?yàn)槊總€(gè)圖像都有不同的數(shù)據(jù)庫(kù)文件。

將一組圖像存儲(chǔ)到磁盤

 store_many_disk(images, labels):
    """ 參數(shù):
        ---------------
        images       圖像數(shù)組 (N, 32, 32, 3) 格式
        labels       標(biāo)簽數(shù)組 (N,1) 格式
    """
    num_images = len(images)

    # 一張一張保存所有圖片
    for i, image in enumerate(images):
        Image.fromarray(image).save(disk_dir / f"{i}.png")

    # 將所有標(biāo)簽保存到 csv 文件
    with open(disk_dir / f"{num_images}.csv", "w") as csvfile:
        writer = csv.writer(
            csvfile, delimiter=" ", quotechar="|", quoting=csv.QUOTE_MINIMAL
        )
        for label in labels:
            writer.writerow([label])

 將一組圖像存儲(chǔ)到 LMDB

def store_many_lmdb(images, labels):
    """ 參數(shù):
        ---------------
        images       圖像數(shù)組 (N, 32, 32, 3) 格式
        labels       標(biāo)簽數(shù)組 (N,1) 格式
    """
    num_images = len(images)

    map_size = num_images * images[0].nbytes * 10

    # 為所有圖像創(chuàng)建一個(gè)新的 LMDB 數(shù)據(jù)庫(kù)
    env = lmdb.open(str(lmdb_dir / f"{num_images}_lmdb"), map_size=map_size)

    # 在一個(gè)事務(wù)中寫入所有圖像
    with env.begin(write=True) as txn:
        for i in range(num_images):
            # 所有鍵值對(duì)都必須是字符串
            value = CIFAR_Image(images[i], labels[i])
            key = f"{i:08}"
            txn.put(key.encode("ascii"), pickle.dumps(value))
    env.close()

將一組圖像存儲(chǔ)到 HDF5

def store_many_hdf5(images, labels):
    """ 參數(shù):
        ---------------
        images       圖像數(shù)組 (N, 32, 32, 3) 格式
        labels       標(biāo)簽數(shù)組 (N,1) 格式
    """
    num_images = len(images)

    # 創(chuàng)建一個(gè)新的 HDF5 文件
    file = h5py.File(hdf5_dir / f"{num_images}_many.h5", "w")

    # 在文件中創(chuàng)建數(shù)據(jù)集
    dataset = file.create_dataset(
        "images", np.shape(images), h5py.h5t.STD_U8BE, data=images
    )
    meta_set = file.create_dataset(
        "meta", np.shape(labels), h5py.h5t.STD_U8BE, data=labels
    )
    file.close()

準(zhǔn)備數(shù)據(jù)集對(duì)比

使用 100000 個(gè)圖像進(jìn)行測(cè)試

cutoffs = [10, 100, 1000, 10000, 100000]

images = np.concatenate((images, images), axis=0)
labels = np.concatenate((labels, labels), axis=0)

# 確保有 100,000 個(gè)圖像和標(biāo)簽
print(np.shape(images))
print(np.shape(labels))

創(chuàng)建一個(gè)計(jì)算方式進(jìn)行對(duì)比

_store_many_funcs = dict(
    disk=store_many_disk, lmdb=store_many_lmdb, hdf5=store_many_hdf5
)

from timeit import timeit

store_many_timings = {"disk": [], "lmdb": [], "hdf5": []}

for cutoff in cutoffs:
    for method in ("disk", "lmdb", "hdf5"):
        t = timeit(
            "_store_many_funcs[method](images_, labels_)",
            setup="images_=images[:cutoff]; labels_=labels[:cutoff]",
            number=1,
            globals=globals(),
        )
        store_many_timings[method].append(t)

        # 打印出方法、截止時(shí)間和使用時(shí)間
        print(f"Method: {method}, Time usage: {t}")

PLOT 顯示具有多個(gè)數(shù)據(jù)集和匹配圖例的單個(gè)圖

import matplotlib.pyplot as plt

def plot_with_legend(
    x_range, y_data, legend_labels, x_label, y_label, title, log=False
):
    """ 參數(shù):
        --------------
        x_range         包含 x 數(shù)據(jù)的列表
        y_data          包含 y 值的列表
        legend_labels   字符串圖例標(biāo)簽列表
        x_label         x 軸標(biāo)簽
        y_label         y 軸標(biāo)簽
    """
    plt.style.use("seaborn-whitegrid")
    plt.figure(figsize=(10, 7))

    if len(y_data) != len(legend_labels):
        raise TypeError(
            "數(shù)據(jù)集的數(shù)量與標(biāo)簽的數(shù)量不匹配"
        )

    all_plots = []
    for data, label in zip(y_data, legend_labels):
        if log:
            temp, = plt.loglog(x_range, data, label=label)
        else:
            temp, = plt.plot(x_range, data, label=label)
        all_plots.append(temp)

    plt.title(title)
    plt.xlabel(x_label)
    plt.ylabel(y_label)
    plt.legend(handles=all_plots)
    plt.show()

# Getting the store timings data to display
disk_x = store_many_timings["disk"]
lmdb_x = store_many_timings["lmdb"]
hdf5_x = store_many_timings["hdf5"]

plot_with_legend(
    cutoffs,
    [disk_x, lmdb_x, hdf5_x],
    ["PNG files", "LMDB", "HDF5"],
    "Number of images",
    "Seconds to store",
    "Storage time",
    log=False,
)

plot_with_legend(
    cutoffs,
    [disk_x, lmdb_x, hdf5_x],
    ["PNG files", "LMDB", "HDF5"],
    "Number of images",
    "Seconds to store",
    "Log storage time",
    log=True,
)

單一圖像的讀取

從 磁盤 讀取

def read_single_disk(image_id):
    """ 參數(shù):
        ---------------
        image_id    圖像的整數(shù)唯一 ID

        返回結(jié)果:
        ---------------
        images       圖像數(shù)組 (N, 32, 32, 3) 格式
        labels       標(biāo)簽數(shù)組 (N,1) 格式
    """
    image = np.array(Image.open(disk_dir / f"{image_id}.png"))

    with open(disk_dir / f"{image_id}.csv", "r") as csvfile:
        reader = csv.reader(
            csvfile, delimiter=" ", quotechar="|", quoting=csv.QUOTE_MINIMAL
        )
        label = int(next(reader)[0])

    return image, label

從 LMDB 讀取

def read_single_lmdb(image_id):
    """ 參數(shù):
        ---------------
        image_id    圖像的整數(shù)唯一 ID

        返回結(jié)果:
        ---------------
        images       圖像數(shù)組 (N, 32, 32, 3) 格式
        labels       標(biāo)簽數(shù)組 (N,1) 格式
    """
    # 打開(kāi) LMDB 環(huán)境
    env = lmdb.open(str(lmdb_dir / f"single_lmdb"), readonly=True)

    # 開(kāi)始一個(gè)新的事務(wù)
    with env.begin() as txn:
        # 進(jìn)行編碼
        data = txn.get(f"{image_id:08}".encode("ascii"))
        # 加載的 CIFAR_Image 對(duì)象
        cifar_image = pickle.loads(data)
        # 檢索相關(guān)位
        image = cifar_image.get_image()
        label = cifar_image.label
    env.close()

    return image, label

從 HDF5 讀取

def read_single_hdf5(image_id):
    """ 參數(shù):
        ---------------
        image_id    圖像的整數(shù)唯一 ID

        返回結(jié)果:
        ---------------
        images       圖像數(shù)組 (N, 32, 32, 3) 格式
        labels       標(biāo)簽數(shù)組 (N,1) 格式
    """
    # 打開(kāi) HDF5 文件
    file = h5py.File(hdf5_dir / f"{image_id}.h5", "r+")

    image = np.array(file["/image"]).astype("uint8")
    label = int(np.array(file["/meta"]).astype("uint8"))

    return image, label

讀取方式對(duì)比

from timeit import timeit

read_single_timings = dict()

for method in ("disk", "lmdb", "hdf5"):
    t = timeit(
        "_read_single_funcs[method](0)",
        setup="image=images[0]; label=labels[0]",
        number=1,
        globals=globals(),
    )
    read_single_timings[method] = t
	print(f"讀取方法: {method}, 使用耗時(shí): {t}")
存儲(chǔ)方法存儲(chǔ)耗時(shí)
Disk1.7 ms
LMDB4.4 ms
HDF52.3 ms

多個(gè)圖像的讀取

將多個(gè)圖像保存為.png文件就可以理解為多次調(diào)用 read_single_method() 這樣。但這不適用于 LMDB 或 HDF5,因?yàn)槊總€(gè)圖像都有不同的數(shù)據(jù)庫(kù)文件。

多圖像調(diào)整代碼

從磁盤中讀取多個(gè)都圖像

def read_many_disk(num_images):
    """ 參數(shù):
        ---------------
        num_images   要讀取的圖像數(shù)量

        返回結(jié)果:
        ---------------
        images       圖像數(shù)組 (N, 32, 32, 3) 格式
        labels       標(biāo)簽數(shù)組 (N,1) 格式
    """
    images, labels = [], []

    # 循環(huán)遍歷所有ID,一張一張地讀取每張圖片
    for image_id in range(num_images):
        images.append(np.array(Image.open(disk_dir / f"{image_id}.png")))

    with open(disk_dir / f"{num_images}.csv", "r") as csvfile:
        reader = csv.reader(
            csvfile, delimiter=" ", quotechar="|", quoting=csv.QUOTE_MINIMAL
        )
        for row in reader:
            labels.append(int(row[0]))
    return images, labels

從LMDB中讀取多個(gè)都圖像

def read_many_lmdb(num_images):
    """ 參數(shù):
        ---------------
        num_images   要讀取的圖像數(shù)量

        返回結(jié)果:
        ---------------
        images       圖像數(shù)組 (N, 32, 32, 3) 格式
        labels       標(biāo)簽數(shù)組 (N,1) 格式
    """
    images, labels = [], []
    env = lmdb.open(str(lmdb_dir / f"{num_images}_lmdb"), readonly=True)

    # 開(kāi)始一個(gè)新的事務(wù)
    with env.begin() as txn:
        # 在一個(gè)事務(wù)中讀取,也可以拆分成多個(gè)事務(wù)分別讀取
        for image_id in range(num_images):
            data = txn.get(f"{image_id:08}".encode("ascii"))
            # CIFAR_Image 對(duì)象,作為值存儲(chǔ)
            cifar_image = pickle.loads(data)
            # 檢索相關(guān)位
            images.append(cifar_image.get_image())
            labels.append(cifar_image.label)
    env.close()
    return images, labels

從HDF5中讀取多個(gè)都圖像

def read_many_hdf5(num_images):
    """ 參數(shù):
        ---------------
        num_images   要讀取的圖像數(shù)量

        返回結(jié)果:
        ---------------
        images       圖像數(shù)組 (N, 32, 32, 3) 格式
        labels       標(biāo)簽數(shù)組 (N,1) 格式
    """
    images, labels = [], []

    # 打開(kāi) HDF5 文件
    file = h5py.File(hdf5_dir / f"{num_images}_many.h5", "r+")

    images = np.array(file["/images"]).astype("uint8")
    labels = np.array(file["/meta"]).astype("uint8")

    return images, labels

_read_many_funcs = dict(
    disk=read_many_disk, lmdb=read_many_lmdb, hdf5=read_many_hdf5
)

準(zhǔn)備數(shù)據(jù)集對(duì)比

創(chuàng)建一個(gè)計(jì)算方式進(jìn)行對(duì)比

from timeit import timeit

read_many_timings = {"disk": [], "lmdb": [], "hdf5": []}

for cutoff in cutoffs:
    for method in ("disk", "lmdb", "hdf5"):
        t = timeit(
            "_read_many_funcs[method](num_images)",
            setup="num_images=cutoff",
            number=1,
            globals=globals(),
        )
        read_many_timings[method].append(t)

        # Print out the method, cutoff, and elapsed time
        print(f"讀取方法: {method}, No. images: {cutoff}, 耗時(shí): {t}")

讀寫操作綜合比較

數(shù)據(jù)對(duì)比

同一張圖表上查看讀取和寫入時(shí)間

plot_with_legend(
    cutoffs,
    [disk_x_r, lmdb_x_r, hdf5_x_r, disk_x, lmdb_x, hdf5_x],
    [
        "Read PNG",
        "Read LMDB",
        "Read HDF5",
        "Write PNG",
        "Write LMDB",
        "Write HDF5",
    ],
    "Number of images",
    "Seconds",
    "Log Store and Read Times",
    log=False,
)

各種存儲(chǔ)方式使用磁盤空間

雖然 HDF5 和 LMDB 都占用更多的磁盤空間。需要注意的是 LMDB 和 HDF5 磁盤的使用和性能在很大程度上取決于各種因素,包括操作系統(tǒng),更重要的是存儲(chǔ)的數(shù)據(jù)大小。

并行操作

通常對(duì)于大的數(shù)據(jù)集,可以通過(guò)并行化來(lái)加速操作。 也就是我們經(jīng)常說(shuō)的并發(fā)處理。

作為.png 文件存儲(chǔ)到磁盤實(shí)際上允許完全并發(fā)。只要圖像名稱不同就可以從不同的線程讀取多個(gè)圖像,或一次寫入多個(gè)文件。

如果將所有 CIFAR 分成十組,那么可以為一組中的每個(gè)讀取設(shè)置十個(gè)進(jìn)程,并且相應(yīng)的處理時(shí)間可以減少到原來(lái)的10%左右。

以上就是Python圖片存儲(chǔ)和訪問(wèn)的三種方式詳解的詳細(xì)內(nèi)容,更多關(guān)于Python圖片存儲(chǔ)訪問(wèn)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Python 控制終端輸出文字的實(shí)例

    Python 控制終端輸出文字的實(shí)例

    今天小編就為大家分享一篇Python 控制終端輸出文字的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-07-07
  • 基于pykeyboard的用法說(shuō)明

    基于pykeyboard的用法說(shuō)明

    這篇文章主要介紹了基于pykeyboard的用法說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-03-03
  • Python3之字節(jié)串bytes與字節(jié)數(shù)組bytearray的使用詳解

    Python3之字節(jié)串bytes與字節(jié)數(shù)組bytearray的使用詳解

    今天小編就為大家分享一篇Python3之字節(jié)串bytes與字節(jié)數(shù)組bytearray的使用詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-08-08
  • 基于python 字符編碼的理解

    基于python 字符編碼的理解

    下面小編就為大家?guī)?lái)一篇基于python 字符編碼的理解。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-09-09
  • python常見(jiàn)進(jìn)制轉(zhuǎn)換方法示例代碼

    python常見(jiàn)進(jìn)制轉(zhuǎn)換方法示例代碼

    Python為我們提供了強(qiáng)大的內(nèi)置函數(shù)和格式化數(shù)字的方法去實(shí)現(xiàn)進(jìn)制轉(zhuǎn)換的功能,下面這篇文章主要給大家介紹了關(guān)于python常見(jiàn)進(jìn)制轉(zhuǎn)換方法的相關(guān)資料,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-05-05
  • 詳解重置Django migration的常見(jiàn)方式

    詳解重置Django migration的常見(jiàn)方式

    這篇文章主要介紹了詳解重置Django migration的常見(jiàn)方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-02-02
  • Python從入門到精通之多線程使用詳解

    Python從入門到精通之多線程使用詳解

    這篇文章主要介紹了Python中的多線程使用,包括創(chuàng)建線程、線程同步、線程間通信以及線程池等基本概念和技巧,文中的示例代碼講解詳細(xì),需要的可以參考一下
    2023-07-07
  • Python內(nèi)置的字符串處理函數(shù)整理

    Python內(nèi)置的字符串處理函數(shù)整理

    Python內(nèi)置的字符串處理函數(shù)整理,收集常用的Python 內(nèi)置的各種字符串處理 函數(shù)的使用方法
    2013-01-01
  • Python attrs提高面向?qū)ο缶幊绦试敿?xì)

    Python attrs提高面向?qū)ο缶幊绦试敿?xì)

    Python是面向?qū)ο蟮恼Z(yǔ)言,一般情況下使用面向?qū)ο缶幊虝?huì)使得開(kāi)發(fā)效率更高,軟件質(zhì)量更好,并且代碼更易于擴(kuò)展,可讀性和可維護(hù)性也更高,但是Python的類寫起來(lái)是真的累,這是可以在創(chuàng)建類的時(shí)候自動(dòng)添加上attrs模塊,下面文章我們就來(lái)介紹這個(gè)東西,需要的朋友可參考一下
    2021-09-09
  • Python 循環(huán)函數(shù)詳細(xì)介紹

    Python 循環(huán)函數(shù)詳細(xì)介紹

    循環(huán)用于重復(fù)執(zhí)行一些程序塊。從上一講的選擇結(jié)構(gòu),我們已經(jīng)看到了如何用縮進(jìn)來(lái)表示程序塊的隸屬關(guān)系。循環(huán)也會(huì)用到類似的寫法。感興趣得小伙伴請(qǐng)參考下面文字得具體內(nèi)容
    2021-09-09

最新評(píng)論