Python基础学习(十)

文章目录

Python多线程编程

进程

  • 进程就是应用的载体,执行的每个py脚本都是启动的一个进程
  • 进程的启动需要CPU以及内存

多进程

进程的创建

进程的模块-- multiprocessing


参数
python 复制代码
"""
进程涉及到的参数如下:
    target  关联的是 当前进程要执行的函数
    name    设置当前进程的名字
    args    以元组的形式,给 当前进程关联的 函数 传参
    kwargs  以元组的形式,给 当前进程关联的 函数 传参

细节
    1、args方式传参,实参的个数 和 数据类型,顺序 必须和 进程关联的函数的形参列表 一致
    2、kwargs方式传参,实参的个数 和 数据类型 必须 和 进程关联的韩式形参列表 一致, 顺序无所谓
"""

#需求:使用多进程模拟小明一边写num行代码,一边听count首音乐

import time, multiprocessing

def coding(name, num):
    for i in range(num):
        print(f'{name}正在敲第{i}行代码')
        time.sleep(0.2)

def music(name, count):
    for i in range(count):
        print(f'{name}正在听第{i}首歌')
        time.sleep(0.2)


if __name__ == '__main__':
    p1 = multiprocessing.Process(target=coding, name='coding', args=('小明', 11))

    p2 = multiprocessing.Process(target=music, name='music', kwargs={'count': 10, 'name': '小明'})

    print(p1.name)
    print(p2.name)

    p1.start()
    p2.start()
获取进程编号
python 复制代码
"""
如何获取进程编号
"""
import time, multiprocessing, os

def coding(name, num):
    for i in range(num):
        print(f'{name}正在敲第{i}行代码')
        time.sleep(0.2)
        print(f'{multiprocessing.current_process().name} : {multiprocessing.current_process().pid}, {os.getpid()}, 父级id:{os.getppid()}')

def music(name, count):
    for i in range(count):
        print(f'{name}正在听第{i}首歌')
        time.sleep(0.2)
        print(f'{multiprocessing.current_process().name} : {multiprocessing.current_process().pid}, {os.getpid()}, 父级id:{os.getppid()}')

if __name__ == '__main__':
    p1 = multiprocessing.Process(target=coding, name='coding', args=('小明', 11))

    p2 = multiprocessing.Process(target=music, name='music', kwargs={'count': 10, 'name': '小明'})

    print(p1.name)
    print(p2.name)

    p1.start()
    p2.start()

    print(f'{multiprocessing.current_process().name} : {multiprocessing.current_process().pid}')
    # print(f'{p1.name} : {p1.pid}')
    # print(f'{p2.name} : {p2.pid}')
数据隔离
python 复制代码
"""
案例: 演示进程之间 数据是相互隔离的.

大白话解释:
    1. 微信 和 QQ都是进程, 它们之间的数据都是 相互隔离的. 即: 微信不能直接访问QQ的数据, QQ也不能直接访问微信的数据.
    2. 下述代码你会发现, 多个子进程相当于把 父进程的资源全部拷贝了一份(注意: main外资源), 即: 子进程相当于父进程的副本.

需求: 定义全局变量 my_list = [], 搞两个进程, 分别实现往里边添加数据, 从里边读取数据, 并观察结果.
"""

# 导包
import multiprocessing, time

# 1. 定义全局变量.
my_list = []

# 2. 定义函数 write_data(), 往: 列表中 添加数据.
def write_data():
    # 为了让效果更明显, 我们添加多个值.
    for i in range(1, 6):
        my_list.append(i)       # 具体添加元素到列表的动作.
        print(f'add: {i}')      # 打印添加细节(过程)
    print(f'write_data函数: {my_list}')       # 添加完毕后, 打印列表结果


# 3. 定义函数 read_data(), 从: 列表中 读取数据.
def read_data():
    # 休眠一会儿, 确保 write_data()函数执行完毕.
    time.sleep(3)
    print(f'read_data函数: {my_list}')       # 打印列表结果


# 4. 在main中测试
if __name__ == '__main__':
    # 4.1 创建两个进程对象.
    p1 = multiprocessing.Process(target=write_data)     # 进程1, 例如: QQ
    p2 = multiprocessing.Process(target=read_data)      # 进程2, 例如: 微信

    # 4.2 开启进程.
    p1.start()
    p2.start()

    # print('看看我打印了几遍? ')   # main函数内的内容, 只执行一次.

print('看看我打印了几遍? ')   # main外资源, 自身要执行一次,  p1进程拷贝1遍,  p2进程拷贝1遍 = 3次
主进程关闭-子进程同步关闭
python 复制代码
"""
案例:
    演示 默认情况下, 主进程会等待子进程执行结束在结束.

需求:
    创建1个子进程, 子进程执行完需要3秒钟, 让主进程1秒就结束, 观察: 整个程序是立即结束, 还是会等待子进程结束再结束.

结论:
    1. 默认情况下, 主进程会等待所有子进程执行结束再结束.
    2. 问: 如何实现, 当主进程结束的时候, 子进程也立即结束呢?
        方式1: 设置子进程为守护进程.   类似于: 公主 和 守护骑士.
        方式2: 手动关闭子进程.

细节:
    1. 当非守护进程结束的时候, 它的所有守护进程都会立即终止, 且释放资源.
    2. 如果是 terminate()方式, 子进程主动结束自己, 则会变成僵尸进程, 不会立即释放资源.

"""

# 导包
import multiprocessing, time


# 1. 定义函数work(), 要被: 子进程关联.
def work():
    for i in range(10):
        print(f'工作中... {i}')
        time.sleep(0.3)     # 总计休眠时间: 0.3 * 10 = 3秒


# 2. 在main函数中测试.
if __name__ == '__main__':
    # 3. 创建子进程.
    p1 = multiprocessing.Process(target=work)

    # 核心细节: 设置p1为守护线程, 因为p1的父进程是main, 所以p1是main的守护进程.
    p1.daemon = True

    # 4. 开启子进程.
    p1.start()

    # 5. 让主进程(main进程)休眠1秒.
    time.sleep(2)

    # 方式2: 在主进程执行结束前, 子进程主动自己关闭自己.
    #p1.terminate()  # 不推荐用, 会变成僵尸进程, 不会主动释放资源, 过段时间会交由(init进程, 充当父进程),来释放资源.

    # 6. 主进程结束, 打印提示语句.
    print('主进程执行结束了!')
主进程会等待子进程执行结束再结束
python 复制代码
"""
案例:
    演示 默认情况下, 主进程会等待子进程执行结束再结束.

需求:
    创建1个子进程, 子进程执行完需要3秒钟, 让主进程1秒就结束, 观察: 整个程序是立即结束, 还是会等待子进程结束再结束.

结论:
    1. 默认情况下, 主进程会等待所有子进程执行结束再结束.
    2. 问: 如何实现, 当主进程结束的时候, 子进程也立即结束呢?
        方式1: 设置子进程为守护进程.   类似于: 公主 和 守护骑士.
        方式2: 手动关闭子进程.

"""

# 导包
import multiprocessing, time


# 1. 定义函数work(), 要被: 子进程关联.
def work():
    for i in range(10):
        print(f'工作中... {i}')
        time.sleep(0.3)     # 总计休眠时间: 0.3 * 10 = 3秒


# 2. 在main函数中测试.
if __name__ == '__main__':
    # 3. 创建子进程.
    p1 = multiprocessing.Process(target=work)
    # 4. 开启子进程.
    p1.start()

    # 5. 让主进程(main进程)休眠1秒.
    time.sleep(1)
    # 6. 主进程结束, 打印提示语句.
    print('主进程执行完成了!')

进程池

优点:

  • 避免了进程的创建与关闭的消耗
进程池的创建--multiprocessing


python 复制代码
# coding:utf-8

import multiprocessing as mp
import os
import time

def work(count):
    print(f'当前数量:{count},当前线程:{os.getpid()}')
    time.sleep(5)


if __name__ == '__main__':
    pool = mp.Pool(4)
    for i in range(10):
        pool.apply_async(work, args=(i, ))
    pool.close() #关闭进程池
    pool.join()	#等待进程池中任务执行完成
 
# 执行结果
当前数量:0,当前线程:29208
当前数量:1,当前线程:26676
当前数量:2,当前线程:26988
当前数量:3,当前线程:14656
当前数量:4,当前线程:29208
当前数量:5,当前线程:14656
当前数量:6,当前线程:26988
当前数量:7,当前线程:26676
当前数量:8,当前线程:29208
当前数量:9,当前线程:26988
获取进程的返回值
python 复制代码
# coding:utf-8

import multiprocessing as mp
import os
import time

def work(count):
    # print(f'当前数量:{count},当前线程:{os.getpid()}')
    time.sleep(5)
    return '当前数量:%s,当前线程:%s' % (count, os.getpid())


if __name__ == '__main__':
    pool = mp.Pool(4)
    results = []
    for i in range(10):
        result = pool.apply_async(work, args=(i, ))
        results.append(result)
    for res in results:
        print(res.get())
#结果
当前数量:0,当前线程:28052
当前数量:1,当前线程:28224
当前数量:2,当前线程:29596
当前数量:3,当前线程:24652
当前数量:4,当前线程:28052
当前数量:5,当前线程:28224
当前数量:6,当前线程:29596
当前数量:7,当前线程:24652
当前数量:8,当前线程:28052
当前数量:9,当前线程:29596

进程锁

进程锁的加锁与解锁
python 复制代码
# coding:utf-8

import multiprocessing as mp
import os
import time

def work(count, lock):
    lock.acquire()
    print(f'当前数量:{count},当前线程:{os.getpid()}')
    time.sleep(5)
    lock.release()
    return '当前数量:%s,当前线程:%s' % (count, os.getpid())


if __name__ == '__main__':
    pool = mp.Pool(4)
    manager = mp.Manager()
    lock = manager.Lock()
    results = []
    for i in range(10):
        pool.apply_async(work, args=(i, lock))

    pool.close()
    pool.join()

进程的通信

队列的创建--multiprocessing
python 复制代码
# coding:utf-8
import json
import multiprocessing
import time


class Work(object):
    def __init__(self, q):
        self.q = q

    def send(self, message):
        if not isinstance(message, str):
            message = json.dumps(message)
        self.q.put(message)

    def recv(self):
        while True:
            result = self.q.get()
            try:
                res = json.loads(result)
            except :
                res = result
            print('recv is %s' % res)

    def seng_all(self):
        for i in range(20):
            self.q.put(i)
            time.sleep(1)

if __name__ == '__main__':
    q = multiprocessing.Queue()
    work = Work(q)
    send = multiprocessing.Process(target=work.send, args=({'name':'zhangsan'},))
    recv = multiprocessing.Process(target=work.recv)

    send_all = multiprocessing.Process(target=work.seng_all)

    send.start()
    recv.start()
    send_all.start()

    # send.join()
    #这里用于阻塞防止还没有发送完成就结束进程,只阻塞最长时间的子进程即可
    send_all.join()
    #终结进程
    recv.terminate()

线程

一个进程中可以有多个线程。

线程的创建--threading

常用方法
参数
python 复制代码
"""
进程涉及到的参数如下:
    target  关联的是 当前进程要执行的函数
    name    设置当前进程的名字
    args    以元组的形式,给 当前进程关联的 函数 传参
    kwargs  以元组的形式,给 当前进程关联的 函数 传参

细节
    1、args方式传参,实参的个数 和 数据类型,顺序 必须和 进程关联的函数的形参列表 一致
    2、kwargs方式传参,实参的个数 和 数据类型 必须 和 进程关联的韩式形参列表 一致, 顺序无所谓
"""

#需求:使用多进程模拟小明一边写num行代码,一边听count首音乐

import time, threading

def coding(name, num):
    for i in range(num):
        print(f'{name}正在敲第{i}行代码')
        time.sleep(0.2)

def music(name, count):
    for i in range(count):
        print(f'{name}正在听第{i}首歌')
        time.sleep(0.2)


if __name__ == '__main__':
    t1 = threading.Thread(target=coding, args=('小明', 11))

    t2 = threading.Thread(target=music, kwargs={'count': 10, 'name': '小明'})

    print(t1.name)
    print(t2.name)

    t1.start()
    t2.start()

进程与线程的关系

  • 进程提供线程执行程序的前置要求,线程在重组的资源配备下,去执行程序

多线程

守护线程
python 复制代码
"""
案例:
    演示 默认情况下, 主线程会等待子线程执行结束在结束.

需求:
    创建1个子线程, 子线程执行完需要3秒钟, 让主线程1秒就结束, 观察: 整个程序是立即结束, 还是会等待子线程结束再结束.

结论:
    1. 默认情况下, 主线程会等待所有子线程执行结束再结束.
    2. 问: 如何实现, 当主线程结束的时候, 子线程也立即结束呢?
        设置子线程为守护线程.   类似于: 公主 和 守护骑士.

结论:
    当非守护线程结束的时候, 和它关联的守护线程, 也会立即结束, 释放资源.
"""

# 导包
import threading, time


# 1. 定义函数work(), 要被: 子线程关联.
def work():
    for i in range(10):
        print(f'工作中... {i}')
        time.sleep(0.3)  # 总计休眠时间: 0.3 * 10 = 3秒


# 2. 在main函数中测试.
if __name__ == '__main__':
    # 3. 创建子线程.
    # 守护线程, 格式1: 创建线程对象的时候, 直接指定.
    # t1 = threading.Thread(target=work, daemon=True)

    t1 = threading.Thread(target=work)
    # 守护线程, 格式2: 创建线程对象后, 通过 daemon属性设置.
    # t1.daemon = True

    # 守护线程, 格式3: 创建线程对象后, 通过 setDaemon()函数设置.
    t1.setDaemon(True)      # 类似于以前我们学的: get_name(), set_name()

    # 4. 开启子线程.
    t1.start()

    # 5. 让主线程(main线程)休眠1秒.
    time.sleep(1)

    # 6. 主线程结束, 打印提示语句.
    print('主线程执行结束了!')
执行顺序
python 复制代码
"""
案例:
    演示多线程代码 的执行顺序.

结论:
    1. 多线程的执行具有 随机性, 因为: 线程是由CPU调度的.
    2. 调度资源常用的两种方式:
        抢占式调度: 谁抢到资源, 谁执行.
            Python, Java用的都是这种思路.
        均分时间片: 每个任务获取CPU的时间都是固定的.
"""

# 导包
import threading
import time


# 1. 定义函数get_info(), 用来打印: 线程信息, 看看当前是哪个线程在执行.
def get_info():
    # 休眠一会儿, 让效果更明显.
    time.sleep(0.3)

    # 1.1 获取当前的线程对象.
    ct = threading.current_thread()

    # 1.2 打印当前线程对象即可.
    print(f'当前的线程对象是: {ct.name}')


# 2. 在main中测试.
if __name__ == '__main__':
    # 3. 为了让效果更明显, 创建多个线程.
    # t1 = threading.Thread(target=get_info)
    # t2 = threading.Thread(target=get_info)
    #
    # t1.start()
    # t2.start()

    for i in range(10):
        t1 = threading.Thread(target=get_info)
        t1.start()
共享资源
python 复制代码
"""
案例: 演示 同一进程的多个线程, 可以共享 该进程的资源.

结论:
    1. 进程之间, 数据相互隔离.        进程 = 软件.
    2. 线程之间, 数据共享.
"""

# 导包
import threading, time

# 1. 定义全局变量.
my_list = []


# 2. 定义函数write_data(), 实现: 往列表中添加数据.
def write_data():
    # 为了效果更明显, 我们添加多个元素.
    for i in range(1, 6):
        # time.sleep(0.1)
        # 往列表中添加元素.
        my_list.append(i)
        # 打印添加的细节
        print(f'add: {i}')

    # 添加之后, 打印结果.
    print(f'write_data函数: {my_list}')


# 3. 定义函数read_data(), 实现: 从列表中读取数据.
def read_data():
    time.sleep(2)     # 为了效果更好看, 加入休眠线程.
    print(f'read_data函数: {my_list}')


# 4. main函数中进行测试.
if __name__ == '__main__':
    # 4.1 创建两个线程对象, 分别关联: write_data(), read_data()函数.
    t1 = threading.Thread(target=write_data)
    t2 = threading.Thread(target=read_data)

    # 4.2 启动线程.
    t1.start()
    t2.start()
操作共享资源-锁
python 复制代码
"""
案例:  线程可以共享全局变量, 同时操作, 可能会出现: 安全问题.

遇到的问题:
    两个线程同时操作共享变量, 进行累加操作, 出现: 累计次数"不够"的情况, 我们要的效果是:  get_sum1: 100W,  get_sum2:200W, 但是结果不是.
产生原因:
    正常情况:
        假设g_num = 0
            第1次循环:  t1线程抢到资源, 对其累加1, 操作后 g_num = 1, t1线程本次操作完毕.
            第2次循环: 假设t2线程抢到了资源, 此时 g_num = 1, 操作之后(累加1), g_num = 2, t2线程本次操作完毕.
        这个是正常情况.

    非正常情况:
        1. 假设 g_num = 0
        2. 假设 t1 线程抢到了资源, 在还没有来得及对 g_num(全局变量)做 累加操作的时候, 被t2线程抢走了资源.
        3. t2线程也会去读取 g_num(全局变量)的值, 此时 g_num = 0
        4. 之后t1 和 t2线程分别开始了 累加操作:
            t1线程, 累加之后,   g_num = 0     ->    g_num = 1
            t2线程, 累加之后,   g_num = 0     ->    g_num = 1
        5. 上述一共累加了 2次, 但是 g_num的值最终只 累加了 1.


"""
import threading

# 需求: 定义两个函数, 分别对全局变量累加100W次, 并打印观察程序的最终运行结果.

# 1. 定义全局变量.
g_num = 0
mutex = threading.Lock()
# 2. 定义函数 get_sum1(), 实现对全局变量累加 100W次
def get_sum1():
    #加锁
    mutex.acquire()
    for i in range(1000000):
        global g_num
        g_num += 1      # 全局变量 + 1
    # 程序计算完毕后, 打印结果.
    #释放锁
    mutex.release()
    print(f'get_sum1函数计算结果: {g_num}')       # 100W

# 3. 定义函数 get_sum2(), 实现对全局变量累加 100W次
def get_sum2():
    mutex.acquire()
    for i in range(1000000):
        global g_num
        g_num += 1      # 全局变量 + 1
    # 程序计算完毕后, 打印结果.
    mutex.release()
    print(f'get_sum2函数计算结果: {g_num}')       # 200W

# 4. 测试
if __name__ == '__main__':
    # 4.1 创建两个线程对象, 分别关联: 两个函数.
    t1 = threading.Thread(target=get_sum1)
    t2 = threading.Thread(target=get_sum2)

    # 4.2 启动线程.
    t1.start()
    t2.start()
操作共享资源-非法值
python 复制代码
"""
案例:  线程可以共享全局变量, 同时操作, 可能会出现: 安全问题.

遇到的问题:
    两个线程同时操作共享变量, 进行累加操作, 出现: 累计次数"不够"的情况, 我们要的效果是:  get_sum1: 100W,  get_sum2:200W, 但是结果不是.
产生原因:
    正常情况:
        假设g_num = 0
            第1次循环:  t1线程抢到资源, 对其累加1, 操作后 g_num = 1, t1线程本次操作完毕.
            第2次循环: 假设t2线程抢到了资源, 此时 g_num = 1, 操作之后(累加1), g_num = 2, t2线程本次操作完毕.
        这个是正常情况.

    非正常情况:
        1. 假设 g_num = 0
        2. 假设 t1 线程抢到了资源, 在还没有来得及对 g_num(全局变量)做 累加操作的时候, 被t2线程抢走了资源.
        3. t2线程也会去读取 g_num(全局变量)的值, 此时 g_num = 0
        4. 之后t1 和 t2线程分别开始了 累加操作:
            t1线程, 累加之后,   g_num = 0     ->    g_num = 1
            t2线程, 累加之后,   g_num = 0     ->    g_num = 1
        5. 上述一共累加了 2次, 但是 g_num的值最终只 累加了 1.


"""
import threading

# 需求: 定义两个函数, 分别对全局变量累加100W次, 并打印观察程序的最终运行结果.

# 1. 定义全局变量.
g_num = 0

# 2. 定义函数 get_sum1(), 实现对全局变量累加 100W次
def get_sum1():
    for i in range(1000000):
        global g_num
        g_num += 1      # 全局变量 + 1
    # 程序计算完毕后, 打印结果.
    print(f'get_sum1函数计算结果: {g_num}')       # 100W

# 3. 定义函数 get_sum2(), 实现对全局变量累加 100W次
def get_sum2():
    for i in range(1000000):
        global g_num
        g_num += 1      # 全局变量 + 1
    # 程序计算完毕后, 打印结果.
    print(f'get_sum2函数计算结果: {g_num}')       # 200W

# 4. 测试
if __name__ == '__main__':
    # 4.1 创建两个线程对象, 分别关联: 两个函数.
    t1 = threading.Thread(target=get_sum1)
    t2 = threading.Thread(target=get_sum2)

    # 4.2 启动线程.
    t1.start()
    t2.start()
主线程会等待子线程执行结束在结束
python 复制代码
"""
案例:
    演示 默认情况下, 主线程会等待子线程执行结束在结束.

需求:
    创建1个子线程, 子线程执行完需要3秒钟, 让主线程1秒就结束, 观察: 整个程序是立即结束, 还是会等待子线程结束再结束.

结论:
    1. 默认情况下, 主线程会等待所有子线程执行结束再结束.
    2. 问: 如何实现, 当主线程结束的时候, 子线程也立即结束呢?
        设置子线程为守护线程.   类似于: 公主 和 守护骑士.

"""

# 导包
import threading, time


# 1. 定义函数work(), 要被: 子线程关联.
def work():
    for i in range(10):
        print(f'工作中... {i}')
        time.sleep(0.3)     # 总计休眠时间: 0.3 * 10 = 3秒


# 2. 在main函数中测试.
if __name__ == '__main__':
    # 3. 创建子线程.
    t1 = threading.Thread(target=work)
    # 4. 开启子线程.
    t1.start()

    # 5. 让主线程(main线程)休眠1秒.
    time.sleep(1)
    # 6. 主线程结束, 打印提示语句.
    print('主线程执行结束了!')

线程池

线程池的创建--concurrent


python 复制代码
# coding:utf-8
import os
import time
from concurrent.futures import ThreadPoolExecutor
import threading

#使用线程锁 只需要全局定义一个线程锁即可
# lock = threading.Lock()
def work(i):
    # lock.acquire()
    print(i, os.getpid())
    time.sleep(1)
    # lock.release()
    return 'result %s' % i


if __name__ == '__main__':
    t = ThreadPoolExecutor(2)
    results = []
    for i in range(10):
        t_result = t.submit(work, (i, ))
        results.append(t_result)

    for res in results:
        print(res.result())

说明:time.sleep 是cpu级别的阻塞,在异步中不可使用,需要使用异步的sleep

异步

异步执行,不会影响主程序的执行,提高执行效率

异步与多线程多进程

  • 轻量级的线程 协程
  • 可以获取异步函数的返回值
  • 主进程需要异步才行

async与await关键字

  • async 定义异步
  • await 执行异步
asyncio调用async函数


python 复制代码
# coding:utf=8
import asyncio
import random
import time


async def a():
    for i in range(10):
        print(i, 'a')
        await asyncio.sleep(random.random() * 2)
    return 'a func'

async def b():
    for i in range(10):
        print(i, 'b')
        await asyncio.sleep(random.random() * 2)
    return 'b func'

async def main():
    result = await asyncio.gather(a(), b())
    print(result)

if __name__ == '__main__':
    start = time.time()
    asyncio.run(main())
    print(time.time() - start)

gevent

比较早的异步依赖包,

  • pip install gevent
  • Microsoft Visual C++
  • pip install wheel
gevent 常用方法
python 复制代码
# coding:utf-8
import os
import random

import gevent

def gevent_a():
    for i in range(10):
        print(i, 'a gevent', os.getpid())
        gevent.sleep(random.random() * 2)
    return 'gevent a result'


def gevent_b():
    for i in range(10):
        print(i, 'b gevent', os.getpid())
        gevent.sleep(random.random() * 2)
    return 'gevent b result'


if __name__ == '__main__':
    g_a = gevent.spawn(gevent_a)
    g_b = gevent.spawn(gevent_b)
    gevent_list = [g_a, g_b]
    result = gevent.joinall(gevent_list)
    print(result[0].value, ' | ',result[1].value)
相关推荐
im_AMBER1 天前
Leetcode 95 分割链表
数据结构·c++·笔记·学习·算法·leetcode·链表
A9better1 天前
嵌入式开发学习日志47——任务创建与就绪列表
单片机·嵌入式硬件·学习
北岛寒沫1 天前
北京大学国家发展研究院 经济学原理课程笔记(第十八课 国内生产总值与物价水平)
经验分享·笔记·学习
轻竹办公PPT1 天前
用 AI 制作 2026 年工作计划 PPT,需要准备什么
大数据·人工智能·python·powerpoint
Mqh1807621 天前
day58 经典时序预测模型
python
Amelia1111111 天前
day44
python
高洁011 天前
10分钟了解向量数据库(1)
python·深度学习·机器学习·transformer·知识图谱
释怀不想释怀1 天前
Linux(复习常见命令)
linux·运维·服务器
DP+GISer1 天前
00基于pytorch的深度学习遥感地物分类全流程实战教程(包含遥感深度学习数据集制作与大图预测)-前言
pytorch·python·深度学习·图像分割·遥感·地物分类