Python多线程、多进程和协程的实例讲解

2023-10-26

线程、进程和协程是什么

线程、进程和协程的详细概念解释和原理剖析不是本文的重点,本文重点讲述在Python中怎样实际使用这三种东西

参考: 进程、线程、协程之概念理解

**进程(Process)**是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。
线程,有时被称为轻量级进程(Lightweight Process,LWP),是程序执行流的最小单元。
**协程:**一个程序可以包含多个协程,可以对比于一个进程包含多个线程,因而下面我们来比较协程和线程:我们知道多个线程相对独立,有自己的上下文,切换受系统控制;而协程也相对独立,有自己的上下文,但是其切换由自己控制,由当前协程切换到其他协程由当前协程来控制。

如果你依然在编程的世界里迷茫,可以加入我们的Python学习扣qun:784758214,看看前辈们是如何学习的。从基础的python脚本到web开发、爬虫、django、数据挖掘等,0基础到项目实战的资料都有整理。送给每一位python的小伙伴!每天分享学习方法和趣味实战教程,技术经验!点击加入我们的 python学习者聚集地

准备工作

磨刀不误砍柴工,在用实例讲解线程、进程和协程怎么使用之前,先准备一些工具:

实际上多线程、多进程和协程,都属于并发编程,并发编程的最重要的目标就是提高程序运行的效率,那么我们需要一个计算一个函数耗时长度的工具,用于对比不同方式程序的运行时间,这里我们写一个函数计时装饰器fn_timer来完成这件事:

def fn_timer(function):
    '''
    函数计时装饰器
    :param function: 函数对象
    :return: 装饰器
    '''
    @wraps(function)
    def function_timer(*args,**kwargs):
        # 起始时间
        t0 = time.time()
        # 调用函数
        result = function(*args,**kwargs)
        # 结束时间
        t1 = time.time()
        # 打印函数耗时
        print '[finished function:{func_name} in {time:.2f}s]'.format(func_name = function.__name__,time = t1 - t0)
        return result
    return function_timer

该装饰器的用法示例:


# 测试
@fn_timer
def add(x,y):
    time.sleep(1.22)
    return x + y

if __name__ == '__main__':
    # 测试
    sum = add(1,2)
    print sum

运行代码输出:

[finished function:test in 1.23s]
3

实际使用中,大规模爬虫程序很适合用并发来实现,所以我们再准备一些网址放在urls列表中,用于测试爬虫程序的效率(都是百度百科的一些词条页面):

# 20个网页
urls = ['https://baike.baidu.com/item/%E8%87%AA%E7%94%B1%E8%BD%AF%E4%BB%B6',
        'https://baike.baidu.com/item/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1%E8%AF%AD%E8%A8%80',
        'https://baike.baidu.com/item/%E5%9F%BA%E9%87%91%E4%BC%9A',
        'https://baike.baidu.com/item/%E5%88%9B%E6%96%B02.0',
        'https://baike.baidu.com/item/%E5%95%86%E4%B8%9A%E8%BD%AF%E4%BB%B6',
        'https://baike.baidu.com/item/%E5%BC%80%E6%94%BE%E6%BA%90%E4%BB%A3%E7%A0%81',
        'https://baike.baidu.com/item/OpenBSD',
        'https://baike.baidu.com/item/%E8%A7%A3%E9%87%8A%E5%99%A8',
        'https://baike.baidu.com/item/%E7%A8%8B%E5%BA%8F/71525',
        'https://baike.baidu.com/item/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80',
        'https://baike.baidu.com/item/C%2B%2B',
        'https://baike.baidu.com/item/%E8%B7%A8%E5%B9%B3%E5%8F%B0',
        'https://baike.baidu.com/item/Web/150564',
        'https://baike.baidu.com/item/%E7%88%B1%E5%A5%BD%E8%80%85',
        'https://baike.baidu.com/item/%E6%95%99%E5%AD%A6',
        'https://baike.baidu.com/item/Unix%20shell',
        'https://baike.baidu.com/item/TIOBE',
        'https://baike.baidu.com/item/%E8%AF%BE%E7%A8%8B',
        'https://baike.baidu.com/item/MATLAB',
        'https://baike.baidu.com/item/Perl']

整合:把函数计时装饰器和urls列表封装在一个类:utils.py中:

# coding:utf-8
from functools import wraps
import time

# 20个网页
urls = ['https://baike.baidu.com/item/%E8%87%AA%E7%94%B1%E8%BD%AF%E4%BB%B6',
        'https://baike.baidu.com/item/%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%A8%8B%E5%BA%8F%E8%AE%BE%E8%AE%A1%E8%AF%AD%E8%A8%80',
        'https://baike.baidu.com/item/%E5%9F%BA%E9%87%91%E4%BC%9A',
        'https://baike.baidu.com/item/%E5%88%9B%E6%96%B02.0',
        'https://baike.baidu.com/item/%E5%95%86%E4%B8%9A%E8%BD%AF%E4%BB%B6',
        'https://baike.baidu.com/item/%E5%BC%80%E6%94%BE%E6%BA%90%E4%BB%A3%E7%A0%81',
        'https://baike.baidu.com/item/OpenBSD',
        'https://baike.baidu.com/item/%E8%A7%A3%E9%87%8A%E5%99%A8',
        'https://baike.baidu.com/item/%E7%A8%8B%E5%BA%8F/71525',
        'https://baike.baidu.com/item/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80',
        'https://baike.baidu.com/item/C%2B%2B',
        'https://baike.baidu.com/item/%E8%B7%A8%E5%B9%B3%E5%8F%B0',
        'https://baike.baidu.com/item/Web/150564',
        'https://baike.baidu.com/item/%E7%88%B1%E5%A5%BD%E8%80%85',
        'https://baike.baidu.com/item/%E6%95%99%E5%AD%A6',
        'https://baike.baidu.com/item/Unix%20shell',
        'https://baike.baidu.com/item/TIOBE',
        'https://baike.baidu.com/item/%E8%AF%BE%E7%A8%8B',
        'https://baike.baidu.com/item/MATLAB',
        'https://baike.baidu.com/item/Perl']


def fn_timer(function):
    '''
    函数计时装饰器
    :param function: 函数对象
    :return: 装饰器
    '''
    @wraps(function)
    def function_timer(*args,**kwargs):
        # 起始时间
        t0 = time.time()
        # 调用函数
        result = function(*args,**kwargs)
        # 结束时间
        t1 = time.time()
        # 打印函数耗时
        print '[finished function:{func_name} in {time:.2f}s]'.format(func_name = function.__name__,time = t1 - t0)
        return result
    return function_timer

# 测试
@fn_timer
def add(x,y):
    time.sleep(1.22)
    return x + y

if __name__ == '__main__':
    # 测试
    sum = add(1,2)
    print sum
    # 输出:
    '''
    [finished function:test in 1.23s]
    3
    '''

实例讲解多线程的用法

从听音乐、看电影讲起

我现在要做两件事情:听音乐、看电影,听一首音乐假如耗时1秒,看一部电影假如耗时5秒,用两个函数定义这两个任务如下:

# 耗时任务:听音乐
def music(name):
    print 'I am listening to music {0}'.format(name)
    time.sleep(1)

# 耗时任务:看电影
def movie(name):
    print 'I am watching movie {0}'.format(name)
    time.sleep(5)

假如我现在要听10首音乐、看2部电影,那么我就有如下几种方案:

方案一:先一个个听完10首音乐,再一个个看完2部电影,顺序完成,代码如下:

# 单线程操作:顺序执行听10首音乐,看2部电影
@fn_timer
def single_thread():
    for i in range(10):
        music(i)
    for i in range(2):
        movie(i)

让我们执行一下这段代码,输出如下:

    I am listening to music 0
    I am listening to music 1
    I am listening to music 2
    I am listening to music 3
    I am listening to music 4
    I am listening to music 5
    I am listening to music 6
    I am listening to music 7
    I am listening to music 8
    I am listening to music 9
    I am watching movie 0
    I am watching movie 1
    [finished function:single_thread in 20.14s]

可以看到,老老实实严格按照先后顺序来一件件做这些事情,所需的总时间和每件事情耗时加起来是一样多的。

方案二:刚刚的方案不太好,太费时间了,那么能不能同时进行一些事情呢?答案是可以的,可以同时听多首音乐,同时看多部电影进行,代码如下:

# 多线程执行:听10首音乐,看2部电影
@fn_timer
def multi_thread():
    # 线程列表
    threads = []
    for i in range(10):
        # 创建一个线程,target参数为任务处理函数,args为任务处理函数所需的参数元组
        threads.append(threading.Thread(target = music,args = (i,)))
    for i in range(2):
        threads.append(threading.Thread(target = movie,args = (i,)))

    for t in threads:
        # 设为守护线程
        t.setDaemon(True)
        # 开始线程
        t.start()
    for t in threads:
        t.join()

执行上述代码,运行结果:

    I am listening to music 0
    I am listening to music 1
    I am listening to music 2
    I am listening to music 3
    I am listening to music 4
    I am listening to music 5
    I am listening to music 6
    I am listening to music 7
    I am listening to music 8
    I am listening to music 9
    I am watching movie 0
    I am watching movie 1
    [finished function:multi_thread in 5.02s]

这次只用了5秒就完成了,完成效率显著提升。这次试用多线程执行多个任务,所有任务最终的总耗时 = 耗时最长的那个单个任务的耗时,即看一部电影的5秒钟时间。

方案三:使用线程池。上面使用多线程的方式比较繁琐,下面使用线程池来实现:

# 使用线程池执行:听10首音乐,看2部电影
@fn_timer
def use_pool():
    # 设置线程池大小为20,如果不设置,默认值是CPU核心数
    pool = Pool(20)
    pool.map(movie,range(2))
    pool.map(music,range(10))
    pool.close()
    pool.join()

执行结果:

    I am listening to music 0
    I am listening to music 1
    I am listening to music 2
    I am listening to music 3
    I am listening to music 4
    I am listening to music 5
    I am listening to music 6
    I am listening to music 7
    I am listening to music 8
    I am listening to music 9
    I am watching movie 0
    I am watching movie 1
    [finished function:use_pool in 6.12s]

可以看出使用线程池反而比手工调度线程多耗时一秒钟,可能是因为线程池内部对线程的调度和线程切换的耗时造成的。

实例:使用多线程下载网页

话不多说,直接上代码,用多线程并发下载20个百度百科网页的实例代码及运行结果如下:

# coding:utf-8
# 测试多线程
import threading
import time
from utils import fn_timer
from multiprocessing.dummy import Pool
import requests
from utils import urls

# 应用:使用单线程下载多个网页的内容
@fn_timer
def download_using_single_thread(urls):
    resps = []
    for url in urls:
        resp = requests.get(url)
        resps.append(resp)
    return resps

# 应用:使用多线程下载多个网页的内容
@fn_timer
def download_using_multi_thread(urls):
    threads = []
    for url in urls:
        threads.append(threading.Thread(target = requests.get,args = (url,)))
    for t in threads:
        t.setDaemon(True)
        t.start()
    for t in threads:
        t.join()

# 应用:使用线程池下载多个网页的内容
@fn_timer
def download_using_pool(urls):
    pool = Pool(20)
    # 第一个参数为函数名,第二个参数一个可迭代对象,为函数所需的参数列表
    resps = pool.map(requests.get,urls)
    pool.close()
    pool.join()
    return resps

def main():
    # 1.使用单线程
    resps = download_using_single_thread(urls)
    print len(resps)
    # 输出:
    '''
    [finished function:download_using_single_thread in 6.18s]
    20
    '''
    # 2. 使用多线程
    download_using_multi_thread(urls)
    # 输出:
    '''
    [finished function:download_using_multi_thread in 0.73s]
    '''

    # 3.使用线程池
    resps = download_using_pool(urls)
    print len(resps)
    # 输出:
    '''
    [finished function:download_using_pool in 0.84s]
    20
    '''

if __name__ == '__main__':
    main()

实例讲解多进程的用法

多进程和进程池的使用

实例代码如下:

# coding:utf-8# 测试多进程import osimport timefrom multiprocessing import Process,Pool,Queuefrom utils import fn_timerimport random# 简单的任务@fn_timerdef do_simple_task(task_name):    print 'Run child process {0}, task name is: {1}'.format(os.getpid(),task_name)    time.sleep(1.2)    return task_name@fn_timer# 1. 测试简单的多进程def test_simple_multi_process():    p1 = Process(target=do_simple_task, args=('task1',))    p2 = Process(target=do_simple_task, args=('task2',))    print 'Process will start...'    p1.start()    p2.start()    p1.join()    p2.join()    print 'Process end.'@fn_timer# 2. 测试使用进程池def test_use_process_pool():    # 创建一个进程池,数字表示一次性同时执行的最大子进程数    pool = Pool(5)    # 任务返回值列表    results = []    # 任务名称列表    task_names = []    for i in range(7):        task_names.append('task{0}'.format(i))    # 并发执行多个任务,并获取任务返回值    results = pool.map_async(do_simple_task,task_names)    print 'Many processes will start...'    pool.close()    pool.join()    print 'All processes end, results is: {0}'.format(results.get())def main():    test_simple_multi_process()    # 输出:    '''    Process will start...    Run child process 1524, task name is: task2    Run child process 1728, task name is: task1    [finished function:do_simple_task in 1.20s]    [finished function:do_simple_task in 1.20s]    Process end.    [finished function:test_simple_multi_process in 1.34s]    '''    test_use_process_pool()    # 输出:    '''    Many processes will start...    Run child process 7568, task name is: task0    Run child process 7644, task name is: task1    Run child process 7628, task name is: task2    Run child process 7620, task name is: task3    Run child process 7660, task name is: task4    [finished function:do_simple_task in 1.20s]    Run child process 7568, task name is: task5    [finished function:do_simple_task in 1.20s]    Run child process 7644, task name is: task6    [finished function:do_simple_task in 1.20s]    [finished function:do_simple_task in 1.20s]    [finished function:do_simple_task in 1.20s]    [finished function:do_simple_task in 1.20s]    [finished function:do_simple_task in 1.20s]    All processes end, results is: ['task0', 'task1', 'task2', 'task3', 'task4', 'task5', 'task6']    [finished function:test_use_process_pool in 2.62s]    '''if __name__ == '__main__':    main()
进程之间的通信

进程间的通信采用队列来实现,实例代码如下:

# coding:utf-8
# 测试多进程
import os
import time
from multiprocessing import Process,Pool,Queue
from utils import fn_timer
import random

# 简单的任务
@fn_timer
def do_simple_task(task_name):
    print 'Run child process {0}, task name is: {1}'.format(os.getpid(),task_name)
    time.sleep(1.2)
    return task_name

@fn_timer
# 1. 测试简单的多进程
def test_simple_multi_process():
    p1 = Process(target=do_simple_task, args=('task1',))
    p2 = Process(target=do_simple_task, args=('task2',))
    print 'Process will start...'
    p1.start()
    p2.start()
    p1.join()
    p2.join()
    print 'Process end.'

@fn_timer
# 2. 测试使用进程池
def test_use_process_pool():
    # 创建一个进程池,数字表示一次性同时执行的最大子进程数
    pool = Pool(5)
    # 任务返回值列表
    results = []
    # 任务名称列表
    task_names = []
    for i in range(7):
        task_names.append('task{0}'.format(i))
    # 并发执行多个任务,并获取任务返回值
    results = pool.map_async(do_simple_task,task_names)
    print 'Many processes will start...'
    pool.close()
    pool.join()

    print 'All processes end, results is: {0}'.format(results.get())

def main():
    test_simple_multi_process()
    # 输出:
    '''
    Process will start...
    Run child process 1524, task name is: task2
    Run child process 1728, task name is: task1
    [finished function:do_simple_task in 1.20s]
    [finished function:do_simple_task in 1.20s]
    Process end.
    [finished function:test_simple_multi_process in 1.34s]
    '''

    test_use_process_pool()
    # 输出:
    '''
    Many processes will start...
    Run child process 7568, task name is: task0
    Run child process 7644, task name is: task1
    Run child process 7628, task name is: task2
    Run child process 7620, task name is: task3
    Run child process 7660, task name is: task4
    [finished function:do_simple_task in 1.20s]
    Run child process 7568, task name is: task5
    [finished function:do_simple_task in 1.20s]
    Run child process 7644, task name is: task6
    [finished function:do_simple_task in 1.20s]
    [finished function:do_simple_task in 1.20s]
    [finished function:do_simple_task in 1.20s]
    [finished function:do_simple_task in 1.20s]
    [finished function:do_simple_task in 1.20s]
    All processes end, results is: ['task0', 'task1', 'task2', 'task3', 'task4', 'task5', 'task6']
    [finished function:test_use_process_pool in 2.62s]
    '''
if __name__ == '__main__':
    main()

实例讲解协程的用法

下面用协程下载同样的20个网页,实例代码如下:

# coding:utf-8
# 测试协程
import requests
import gevent
import utils
from utils import fn_timer
from gevent.pool import Pool
from gevent import monkey
# 打动态补丁,把标准库中的thread/socket等替换掉,让它们变成非阻塞的
monkey.patch_all()

session = requests.Session()
session.headers['User-Agent'] = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.131 Safari/537.36'

@fn_timer
def download_using_single_thread(urls):
    '''
    顺序执行下载多个网页
    :param urls: 要下载的网页内容
    :return: 响应列表
    '''
    resps = []
    for url in urls:
        resps.append(session.get(url))
    return resps

@fn_timer
def download_using_coroutine(urls):
    '''
    使用协程下载
    :param urls: 要下载的网页内容
    :return: 响应列表
    '''
    spawns = []
    for url in urls:
        spawns.append(gevent.spawn(session.get,url))
    # 在遇到IO操作时,gevent会自动切换,并发执行(异步IO)
    rets = gevent.joinall(spawns)
    # joinall函数会返回gevent.greenlet.Greenlet对象的列表,如果想要获得每次调用session.get函数的返回结果,还需分别调用每个Greenlet对象的get函数
    results = [ret.get() for ret in rets]

@fn_timer
def download_using_coroutine_pool(urls):
    # 创建协程池,并设置最大并发量
    pool = Pool(20)
    # pool.map函数直接返回每次调用session.get函数返回的结果列表
    rets = pool.map(session.get,urls)

def main():
    # 1.使用单线程下载20个网页
    download_using_single_thread(utils.urls)
    # 输出:
    '''
    [finished function:download_using_single_thread in 1.83s]
    '''

    # 2.使用协程下载20个网页
    download_using_coroutine(utils.urls)
    # 输出:
    '''
    [finished function:download_using_coroutine in 0.69s]
    '''

    # 3.使用协程池下载20个网页
    download_using_coroutine_pool(utils.urls)
    # 输出:
    '''
    [finished function:download_using_coroutine_pool in 0.78s]
    '''

if __name__ == '__main__':
    main()

可以发现,协程的效率也是非常高的。

多线程、多进程和协程并发效率的对比

下面分别使用线程池、进程池和协程池下载100个相同的网页,来对比其效率:

在学习过程中有什么不懂得可以加我的
python学习交流扣扣qun,784758214
群里有不错的学习视频教程、开发工具与电子书籍。
与你分享python企业当下人才需求及怎么从零基础学习好python,和学习什么内容
# coding:utf-8
# 对比多线程、多进程和协程下载网页
import requests
import utils
from utils import fn_timer
from multiprocessing.dummy import Pool as thread_pool
from multiprocessing import Pool as process_pool
from gevent.pool import Pool as gevent_pool
from gevent import monkey
# 打动态补丁,把标准库中的thread/socket等替换掉,让它们变成非阻塞的
monkey.patch_all()

session = requests.Session()
session.headers['User-Agent'] = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.131 Safari/537.36'

# 1. 使用线程池下载多个网页的内容
@fn_timer
def download_using_thread_pool(urls):
    pool = thread_pool(100)
    # 第一个参数为函数名,第二个参数一个可迭代对象,为函数所需的参数列表
    resps = pool.map(session.get,urls)
    pool.close()
    pool.join()
    return resps

# 2. 测试使用进程池
@fn_timer
def download_using_process_pool(urls):
    # 创建一个进程池,数字表示一次性同时执行的最大子进程数
    pool = process_pool(100)
    # 任务返回值列表
    results = []
    # 并发执行多个任务,并获取任务返回值
    results = pool.map_async(session.get,urls)
    pool.close()
    pool.join()
    return results.get()

# 3. 使用协程池下载
@fn_timer
def download_using_coroutine_pool(urls):
    # 创建协程池,并设置最大并发量
    pool = gevent_pool(100)
    pool.map(session.get,urls)

def main():
    # 1. 使用线程池下载100个网页
    download_using_thread_pool(utils.urls * 5)
    # 输出:
    '''
    [finished function:download_using_thread_pool in 3.68s]
    '''

    # 2. 使用进程池下载100个网页
    download_using_process_pool(utils.urls * 5)
    # 输出:
    '''
    卡死了
    '''

    # 3.使用协程池下载20个网页
    download_using_coroutine_pool(utils.urls * 5)
    # 输出:
    '''
    [finished function:download_using_coroutine_pool in 3.46s]
    '''

if __name__ == '__main__':
    main()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python多线程、多进程和协程的实例讲解 的相关文章

  • x 或 y:可接受的习语,还是混淆?

    我必须从可能为 None 的变量中提取值 并考虑一些默认值 我首先写了这段代码 if self maxTiles is None maxX maxY 2 2 else maxX maxY self maxTiles 然后我意识到我可以将其缩
  • AWS Lambda 错误:无法导入模块“function_name”:没有名为“module._module”的模块

    阅读后请特别查看屏幕截图 我正在 AWS Lambda 上部署一个使用该包的 python 脚本impyla它依赖于包bitarray from impala dbapi import connect 我的Python文件名为authori
  • 在Python中解析空选项

    我有一个应用程序 允许您将事件数据发送到自定义脚本 您只需布置命令行参数并指定什么事件数据与什么参数相匹配 问题是这里没有真正的灵活性 您制定的每个选项都将被使用 但并非每个选项都必须有数据 因此 当应用程序构建要发送到脚本的字符串时 某些
  • 将 python scikit learn 模型导出到 pmml

    我想将 python scikit learn 模型导出到 PMML 中 什么 python 包最适合 我读到Augustus https github com opendatagroup augustus 但我找不到任何使用 scikit
  • 如何在 for 循环中跳过一些迭代

    在 python 中 我通常简单地循环遍历范围 for i in range 100 do something 但现在我想跳过循环中的几个步骤 更具体地说 我想要类似的东西continue 10 这样它就会跳过整个循环并将计数器增加 10
  • AWS Lambda - 在区域之间自动复制 EC2 快照?

    我想创建一个 Lambda 函数 python 它将自动将已创建的快照复制到另一个区域 我已联系 AWS Support 他们只向我发送了用于 RDS 数据库的 GitHub 脚本 没有 EC2 快照复制脚本 任何帮助都会很棒 谢谢 是的
  • 在 AWS Elastic Beanstalk 中部署 Flask 应用程序

    当我部署 Flask 应用程序时 它显示成功 但是当我检索日志时 我看到错误 找不到 Flask 我的需求文件中有烧瓶 任何帮助 Sat Jan 11 06 51 50 503908 2020 error pid 3393 remote 1
  • 为什么通过selenium切换到alert不稳定?

    为什么通过selenium切换到alert不稳定 例如 1 运行代码 一切顺利 一切都很顺利 但如果这段代码在几分钟内运行 那么可能会出现错误 例如 没有可以单击的元素 等等 2 在一个站点上有一个警报窗口 alert driver swi
  • 在用户提交的正则表达式中查找捕获组

    我有一个 python 应用程序 需要处理用户提交的正则表达式 出于性能考虑 我想禁止捕获组和反向引用 我的想法是使用另一个正则表达式来验证用户提交的正则表达式不包含任何命名或未命名的组捕获 如下所示 def validate user r
  • 模拟导入失败

    我该如何制作import pkg失败moduleA py 我可以打补丁pkg如果从中导入某些内容则会失败 否则不会失败 test py import os import moduleA from unittest mock import p
  • OpenCV 在使用 anaconda 的 Linux 上无法与 python 正常工作。收到 cv2.imshow() 未实现的错误

    这就是我得到的确切错误 我的操作系统是 Ubuntu 16 10 OpenCV 错误 未指定错误 该功能未实现 使用 Windows GTK 2 x 或 Carbon 支持重新构建库 如果您使用的是 Ubuntu 或 Debian 请安装
  • SyntaxError:多个异常类型必须用括号括起来

    我是初学者 在使用 python 安装 pycaw 进行音频控制后遇到问题 在放置 pycaw 的基本初始化代码时 出现以下错误 Traceback most recent call last File c Users volumeCont
  • 插入失败“OperationalError:没有这样的列”

    我尝试使用我尝试修复的姓名和电话创建一个数据库 但它会随时向我重播 File exm0 py line 14 in
  • numpy.polyfit 没有关键字“cov”

    我试图使用 polyfit 来找到一组数据的最佳拟合直线 但我还需要知道参数的不确定性 所以我也想要协方差矩阵 在线文档建议我写 polyfit x y 2 cov True 但这给出了错误 类型错误 polyfit 得到了意外的关键字参数
  • python中不规则点之间的坐标列表

    想象一下 我们为 x 和 y 随机选择两个介于 0 到 100 之间的点 例如 95 7 35 6 现在使用简单的 pygame draw line 函数 我们可以轻松地在这些点之间绘制一条没有任何间隙的线 我的问题是 我们如何找到两点之间
  • 了解 Tensorflow 中的 while 循环

    我正在使用用于 Tensorflow 的 Python API https www tensorflow org api docs python 我正在努力实施罗森布罗克函数 https www sfu ca ssurjano rosen
  • 来自字典列表列表的 Pandas DataFrame

    我有一个数据结构 它是字典列表的列表 Height 86 Left 1385 Top 215 Width 86 Height 87 Left 865 Top 266 Width 87 Height 103 Left 271 Top 506
  • Python 中的“lambda”是什么意思,最简单的使用方法是什么?

    您能否给出一个示例和其他示例来说明何时以及何时不使用 Lambda 我的书给了我一些例子 但它们很令人困惑 拉姆达 起源于拉姆达演算 http en wikipedia org wiki Lambda calculus和 AFAIK 首先实
  • jupyter run magic 将参数传递给笔记本

    当您在第一个 jupyter 笔记本 first ipynb 中时 您可以执行第二个 但如何传递参数呢 假设第二个有以下内容 xx 10 您可以从第一个调用第二个 如下所示 run second ipynb xx will print 10
  • 预提交钩子 git 错误

    我正在尝试在 python 中执行预提交 git hook 以检查文件的行长度是否小于 80 个字符 但是我收到没有此类文件 目录的错误 我在 fedora 上并设置了 usr bin python help 将不胜感激 usr bin e

随机推荐

  • java实现手机号验证码登录功能,并限制同一个IP10分钟以内最多发3次。保姆级教程

    第一步 引入依赖
  • Microsoft 登陆微软账号一直加载不进去 解决方案整理

    今天我登陆visual studio的时候发现到期了 要我登陆Microsoft账号 试了很久 之前其实就发现了我登陆微软账户会很卡 无论是OneNote还是其他微软的软件都卡 还进不去微软商店 加速器也没有用 我找了很多方法 不是每一种都
  • Hive(6) Hive的DDL语句详解-创建数据库以及Hive表的分类和创建

    Hive 2 DDL语句 DDL 数据定义语言 数据库操作 创建数据库 创建数据库 create database if not exists lt 表名 gt comment lt 表的说明 gt localtion lt 路径 gt w
  • Eclipse可以查看源码的插件步骤

    Eclipse可以查看源码的插件步骤 一 点击window Eclipse可以查看源码的插件步骤 图片 带尺寸的图片 二 点击preference 进入一下页面 三 点击java 再点击Installed JREs 再双击jdk1 8 或D
  • 服务器ME位置,me配置服务器前端文件路径

    me配置服务器前端文件路径 内容精选 换一换 AOM支持虚机 这里的虚机指操作系统为Linux的弹性云服务器或裸金属服务器 日志采集 即采集您自定义的日志文件并展现在AOM界面中 以供您检索 使用该功能前首先要配置日志采集路径 配置方法详见
  • Day16-20 Python语言进阶

    Python语言进阶 重要知识点 生成式 推导式 的用法 prices AAPL 191 88 GOOG 1186 96 IBM 149 24 ORCL 48 44 ACN 166 89 FB 208 09 SYMC 21 29 用股票价格
  • 网络编程总结和正则表达式

    今天主要学习了网络编程和正则表达式 网络编程概述 Java是 Internet 上的语言 它从语言级上提供了对网络应用程 序的支持 程序员能够很容易开发常见的网络应用程序 Java提供的网络类库 可以实现无痛的网络连接 联网的底层 细节被隐
  • 2020最佳mac端app新鲜出炉!今年,你发现了哪些好软件?

    虽然2020年对于整个世界来说都是多舛的一年 但不管怎么说生活都在继续 而进入十二月之后 各大年度榜单也逐渐出现在了大家的视野里 今天为大家总结了12款2020年度最佳mac app 有了它们的加成 mac的使用体验更加流畅不说 生产力也能
  • C#调用带结构体指针的C Dll的方法

    在C 中调用C C 类的DLL的时候 有时候C的接口函数包含很多参数 而且有的时候这些参数有可能是个结构体 而且有可能是结构体指针 那么在C 到底该如何安全的调用这样的DLL接口函数呢 本文将详细介绍如何调用各种参数的方法 一 调用接口仅含
  • Flask电影网站项目

    1 开发环境搭建 1 1 Windows环境 下载Python 下载PyCharm 下载virtualenv 下载MySQL 可以安转一个数据库GUI 1 2 Linux环境 下载VMware Workstation Pro 下载ubunt
  • Redhat/CentOS Linux 进入单用户模式

    以 CentOS 7 9 和 Redhat 8 2 为例进行操作 因为CentOS是Redhat的发行版 所以同版本号界面和操作是一样的 CentOS 7 9 开机在 grub 引导界面时 按下 e 键进入编辑模式 找到 linux16 这
  • Ubuntu安装软件步骤

    Ubuntu安装软件步骤 sudo apt get update sudo apt get install flex bison gperfbuild essential curl zlib1g dev g multilib g 4 4 m
  • Source Insight 4.0 下载 安装 配置

    目录 下载地址 安装 打开 试用 导入工程 代码 1 新建一个项目 project 2 填充项目名及代码路径 3 这个直接点OK 4 导入项目文件 5 重建一下项目 6 打开项目文件 project Files 修改source insig
  • CS162 13-17 虚拟内存

    起源 为啥我们需要虚拟内存 需求是啥 可以给程序提供一个统一的视图 比如多个程序运行同一个代码段的话 同一个kernel 就可以直接共享 cpu眼里的虚拟内存 无限内存的假象 设计迭代过程 为啥这样设计 一个迭代过程 用上下界来做 缺点 还
  • Basic Level 1065 单身狗 (25分)

    题目 单身狗 是中文对于单身人士的一种爱称 本题请你从上万人的大型派对中找出落单的客人 以便给予特殊关爱 输入格式 输入第一行给出一个正整数 N 50 000 是已知夫妻 伴侣的对数 随后 N 行 每行给出一对夫妻 伴侣 为方便起见 每人对
  • cv2.error: OpenCV(4.6.0) :-1: error: (-5:Bad argument) in function ‘seamlessClone‘

    Can t parse p Sequence item with index 0 has a wrong type 1 软件环境 2 问题描述 3 解决方法 4 结果预览 1 软件环境 Windows10 教育版64位 Python 3 6
  • 函数式接口

    接口 package cn dali5 code01 函数式接口 有且仅有一个抽象方法的接口 可以有其他的方法 默认 静态 私有 函数式接口 适用于函数式编程场景的接口 Java中函数式编程的提现就是lambda表达式 所以函数式接口就是可
  • python子类定义报错:TypeError: __init__() missing 1 required positional argument: ‘prilege‘

    在学习 Python编程 从入门到实践 中类这一章节 其中子类的案例代码如下 class Car snip class Battery 一次模拟电动汽车电瓶的简单尝试 def init self battery size 70 初始化电瓶的
  • html5media使用api,html5中media(播放器)的api使用指南.pdf

    代码如下 HTML Audio API HTML5 Audio API HTML5 Audio API demo by target blank gt LearnShare Last update 2013 04 23 20 40 00 a
  • Python多线程、多进程和协程的实例讲解

    线程 进程和协程是什么 线程 进程和协程的详细概念解释和原理剖析不是本文的重点 本文重点讲述在Python中怎样实际使用这三种东西 参考 进程 线程 协程之概念理解 进程 Process 是计算机中的程序关于某数据集合上的一次运行活动 是系