【100天精通python】Day25:python的编程方式以及并发编程详解

简介: 【100天精通python】Day25:python的编程方式以及并发编程详解

专栏导读

专栏订阅地址:https://blog.csdn.net/qq_35831906/category_12375510.html

1 python的编程方式

      Python是一种高级编程语言,具有简洁易读的语法和丰富的标准库,广泛用于多个领域,包括Web开发、数据科学、人工智能、网络编程等。Python的编程方式可以概述如下:

  1. 脚本编程:Python适合用作脚本语言,能够快速编写并运行简单的脚本,处理各种任务,如文件操作、数据处理等。
  2. 面向对象编程:Python支持面向对象编程,可以创建类和对象,并通过继承、封装和多态等特性实现代码的模块化和重用。
  3. 函数式编程:Python支持函数式编程,可以将函数作为参数传递、返回函数,以及使用高阶函数等功能,方便实现函数的复合和抽象。
  4. 异步编程:Python提供asyncio模块,支持异步编程,允许在单线程中处理多个I/O任务,提高程序的并发性能。
  5. 并发编程:Python提供threadingmultiprocessing模块,允许通过多线程和多进程实现并发编程,充分利用多核CPU。
  6. 其他特性:Python还具有列表推导、生成器表达式、装饰器等特性,使得代码更加简洁、高效。

总体而言,Python的编程方式简单灵活,适合快速开发,适用于各种规模的项目,成为了许多开发者和科学家的首选语言。

2 顺序编程

   顺序编程是指按照代码的书写顺序依次执行程序,从上到下逐行执行代码。这是最简单、最基本的编程方式,适用于简单的任务和小规模的程序。

示例:

# 顺序编程示例
def add(a, b):
    return a + b
def multiply(a, b):
    return a * b
x = 5
y = 10
result1 = add(x, y)
result2 = multiply(x, y)
print("Result of addition:", result1)
print("Result of multiplication:", result2)

3 面向对象编程

面向对象编程是一种编程范式,通过创建类和对象来表示真实世界的事物和关系。在面向对象编程中,数据和功能被组织成对象,并通过类定义属性和方法。

示例:

# 面向对象编程示例
class Rectangle:
    def __init__(self, width, height):
        self.width = width
        self.height = height
    def area(self):
        return self.width * self.height
    def perimeter(self):
        return 2 * (self.width + self.height)
rect = Rectangle(5, 10)
print("Area:", rect.area())
print("Perimeter:", rect.perimeter())

4 函数式编程

函数式编程是一种编程范式,将计算视为数学函数的应用,强调函数的纯粹性和不可变性。在函数式编程中,函数可以作为参数传递给其他函数,也可以返回其他函数。

示例:

# 函数式编程示例
def add(a, b):
    return a + b
def multiply(a, b):
    return a * b
def apply_operation(operation, a, b):
    return operation(a, b)
x = 5
y = 10
result1 = apply_operation(add, x, y)
result2 = apply_operation(multiply, x, y)
print("Result of addition:", result1)
print("Result of multiplication:", result2)

5 并发编程

       并发编程是指同时执行多个任务或处理多个操作的编程方式,它可以提高程序的执行效率和响应性。Python提供了多种并发编程的方式,包括多线程、多进程和异步编程。

5.1 多线程编程

       多线程是一种并发编程的方式,它允许程序同时执行多个线程,每个线程处理一个独立的任务。Python的threading模块提供了多线程的支持。

示例:

import threading
import time
def print_numbers():
    for i in range(1, 6):
        print(i)
        time.sleep(1)
def print_letters():
    for letter in 'ABCDE':
        print(letter)
        time.sleep(1)
if __name__ == "__main__":
    # 创建两个线程
    thread1 = threading.Thread(target=print_numbers)
    thread2 = threading.Thread(target=print_letters)
    # 启动线程
    thread1.start()
    thread2.start()
    # 等待两个线程执行完成
    thread1.join()
    thread2.join()
    print("All threads have finished.")

       在上面的示例中,我们定义了两个函数print_numbers和print_letters,分别用于打印数字和字母。然后,我们创建了两个线程thread1和thread2,并将这两个函数作为线程的执行目标。通过调用start方法启动线程,它们会并发执行。最后,我们使用join方法等待两个线程执行完成,然后输出"All threads have finished."。

       需要注意的是,由于Python的全局解释器锁(Global Interpreter Lock,GIL),多线程并不能发挥真正的并行执行能力,适合在IO密集型任务中使用,如网络请求、文件读写等。对于CPU密集型任务,建议使用多进程编程,即使用multiprocessing模块来实现。

threading模块常用用法

threading模块是Python中用于多线程编程的标准库,它提供了创建和管理线程的类和函数。

1 创建线程:

import threading
def my_function():
    # 任务代码
my_thread = threading.Thread(target=my_function)

2 启动线程:

my_thread.start()

3 等待线程执行完毕:

my_thread.join()
4 获取当前活动线程数量:
threading.active_count()
5 获取当前线程对象:
threading.current_thread()
6 设置线程名字:
my_thread = threading.Thread(target=my_function, name="MyThread")
7 获取线程名字:
my_thread.getName()
8 设置守护线程(在主线程退出时自动退出):
my_thread.daemon = True
9 线程同步 - 使用Lock:
lock = threading.Lock()
def my_function():
    lock.acquire()
    # 临界区代码
    lock.release()

10 线程同步 - 使用Semaphore(信号量):

semaphore = threading.Semaphore(2)  # 限制同时执行的线程数为2
def my_function():
    semaphore.acquire()
    # 临界区代码
    semaphore.release()

11 线程同步 - 使用Condition:

condition = threading.Condition()
def producer():
    with condition:
        # 生产者代码
        condition.notify()  # 通知消费者
def consumer():
    with condition:
        condition.wait()  # 等待生产者通知
        # 消费者代码

12 线程间通信 - 使用Queue:

import queue
my_queue = queue.Queue()
def producer():
    my_queue.put("hello")
def consumer():
    data = my_queue.get()
    print(data)

注意:由于Python中的全局解释器锁(GIL),多线程并不能发挥真正的并行执行能力。对于CPU密集型任务,建议使用多进程编程(multiprocessing模块)。对于IO密集型任务,多线程是一个不错的选择,可以在IO等待时切换到其他线程,提高程序的响应性。

5.2 多进程编程

        多进程是一种并发编程的方式,它允许程序同时执行多个进程,每个进程运行在独立的内存空间中。Python的multiprocessing模块提供了多进程的支持。

multiprocessing 模块常用用法

 multiprocessing是Python标准库中用于实现多进程并发编程的模块。它提供了类似于threading模块的接口,但是可以在多个进程中并行执行任务,从而充分利用多核CPU的优势。以下是multiprocessing模块的一些常用用法:

  1. 创建进程:使用multiprocessing.Process类可以创建一个新的进程。
  2. 启动进程:调用进程对象的start()方法可以启动一个新的进程并开始执行任务。
  3. 进程间通信:使用multiprocessing.Queuemultiprocessing.Pipe等类来实现多个进程之间的通信。
  4. 进程池:使用multiprocessing.Pool类可以创建一个进程池,可以方便地进行进程复用和任务调度。

下面是一个简单的示例,演示了如何使用multiprocessing模块来实现多进程并发编程:

import multiprocessing
import time
def worker(name):
    print(f"Worker {name} started")
    time.sleep(2)
    print(f"Worker {name} finished")
if __name__ == "__main__":
    # 创建两个新进程
    p1 = multiprocessing.Process(target=worker, args=("A",))
    p2 = multiprocessing.Process(target=worker, args=("B",))
    # 启动进程
    p1.start()
    p2.start()
    # 等待两个进程结束
    p1.join()
    p2.join()
    print("All processes finished")

输出:

       在上面的示例中,我们定义了一个worker函数,用于模拟每个进程执行的任务。然后使用multiprocessing.Process类创建两个新的进程,并分别启动它们。最后,使用join()方法等待两个进程结束,并在所有进程完成后输出"All processes finished"。

       需要注意的是,在使用multiprocessing模块时,要确保主程序的代码放在if __name__ == "__main__":语句块中,以避免在子进程中重复执行主程序的代码。同时,multiprocessing模块在Windows系统下使用时,需要在if __name__ == "__main__":语句块中创建进程,以防止进程无限递归。

       在上面的示例代码中,我们没有涉及进程间通信和进程池的用法。下面我们将完善示例代码,包含进程间通信和进程池的使用:

import multiprocessing
import time
def worker(name, queue):
    print(f"Worker {name} started")
    time.sleep(2)
    queue.put(f"Result from worker {name}")
if __name__ == "__main__":
    multiprocessing.set_start_method('spawn')
    multiprocessing.freeze_support()
    # 创建进程间通信的队列
    manager = multiprocessing.Manager()
    queue = manager.Queue()
    # 创建进程池,池中有2个进程
    pool = multiprocessing.Pool(processes=2)
    # 启动进程池中的进程,每个进程执行worker函数,并使用 apply 方法改为阻塞方式
    pool.apply(worker, args=("A", queue))
    pool.apply(worker, args=("B", queue))
    # 关闭进程池,不再接受新的任务
    pool.close()
    # 等待所有进程完成
    pool.join()
    # 从队列中获取进程的结果
    results = []
    while not queue.empty():
        results.append(queue.get())
    print("All processes finished")
    print("Results:", results)

输出:

        在上面的示例代码中,我们使用multiprocessing.Queue实现了进程间的通信。每个子进程在完成任务后,会将结果放入队列中,主进程再从队列中获取这些结果。同时,我们使用multiprocessing.Pool创建了一个包含两个进程的进程池,并通过apply_async方法向进程池中提交任务。

       需要注意的是,进程池的大小可以根据系统的CPU核心数和任务的复杂度进行调整,以充分利用系统资源。

       以上示例代码展示了进程间通信和进程池的使用,使得多个进程可以并发执行任务,并在需要时进行通信。这样可以提高程序的效率和并发处理能力。

注意:

     在 Windows 上,为了让 multiprocessing 正常工作,需要在创建进程前添加 multiprocessing.set_start_method('spawn') 和 multiprocessing.freeze_support() 代码,这样可以确保进程间通信的正常执行。

       另外,请注意,有些 IDE(如IDLE等)对于多进程的输出支持不够友好,有时无法显示子进程的输出。您可以尝试在命令行中运行代码,看看是否能够正常输出。

       如果在命令行中运行仍然没有输出,可能存在其他问题,比如与操作系统或Python环境有关的问题。您可以尝试在不同的环境中运行代码,或者检查是否有其他异常出现。

5.3 异步编程

        异步编程是一种并发编程的方式,它允许程序在执行耗时操作时,不会阻塞其他任务的执行,从而提高程序的性能和响应性。在Python中,异步编程通常使用asyncio模块来实现。

       异步编程的关键是使用"async"和"await"关键字来定义异步函数和执行异步操作。异步函数可以通过"async def"关键字来定义,而在异步函数内部,可以使用"await"关键字来等待异步操作的完成。

import asyncio
async def foo():
    print("Start foo")
    await asyncio.sleep(2)
    print("End foo")
async def bar():
    print("Start bar")
    await asyncio.sleep(1)
    print("End bar")
# 创建一个事件循环
loop = asyncio.get_event_loop()
# 执行异步任务
loop.run_until_complete(asyncio.gather(foo(), bar()))
# 关闭事件循环
loop.close()

       在上面的示例中,我们定义了两个异步函数foo和bar,分别模拟了耗时的任务。在主程序中,我们使用asyncio.gather函数来同时运行这两个异步任务,并使用loop.run_until_complete来运行事件循环,直到所有异步任务完成。

       异步编程在处理IO密集型任务时特别有用,例如网络请求、文件读写等。通过使用异步编程,我们可以在等待IO操作的同时继续执行其他任务,从而提高程序的效率。

       需要注意的是,在异步编程中,不能在普通的同步函数内调用异步函数,而只能在其他异步函数内调用。另外,要确保所有的异步操作都是非阻塞的,否则可能会导致整个程序的阻塞。

       总的来说,异步编程是一种强大的并发编程方式,可以显著提高程序的性能和响应性。但它也需要仔细设计和考虑,以确保正确处理异步操作和避免潜在的并发问题。  


asyncio 模块常用用法

 asyncio是Python标准库中提供的异步编程模块,用于编写异步代码和管理事件循环。它提供了一组用于定义异步函数和处理异步任务的工具。以下是asyncio模块的一些常用用法:

  1. 定义异步函数:使用async def关键字来定义异步函数,这些函数可以包含await关键字来等待异步操作的完成。
  2. 创建事件循环:使用asyncio.get_event_loop()来获取一个事件循环对象。
  3. 运行事件循环:使用loop.run_until_complete()来运行事件循环,直到指定的异步任务完成。
  4. 并发执行异步任务:使用asyncio.gather()函数可以同时运行多个异步任务,并等待它们全部完成。
  5. 异步IO操作:使用asyncio提供的异步IO函数,例如asyncio.open()asyncio.write(),来执行非阻塞的IO操作。

下面是一个简单的示例,演示了如何使用asyncio模块来并发执行异步任务:

import asyncio
async def foo():
    print("Start foo")
    await asyncio.sleep(2)
    print("End foo")
async def bar():
    print("Start bar")
    await asyncio.sleep(1)
    print("End bar")
async def main():
    # 并发执行foo和bar函数
    await asyncio.gather(foo(), bar())
# 创建一个事件循环
loop = asyncio.get_event_loop()
# 运行事件循环,直到main函数完成
loop.run_until_complete(main())
# 关闭事件循环
loop.close()

       在上面的示例中,我们定义了两个异步函数foo和bar,然后在main函数中使用asyncio.gather()函数同时运行这两个异步函数。最后,通过事件循环的run_until_complete()方法运行main函数,直到所有异步任务完成。

       需要注意的是,在使用asyncio进行异步编程时,要避免在同步代码中调用异步函数,否则可能会导致阻塞。尽量在异步环境中使用await关键字来等待异步操作的完成,以确保程序的高效性和响应性。


目录
相关文章
|
6天前
|
机器学习/深度学习 人工智能 TensorFlow
人工智能浪潮下的自我修养:从Python编程入门到深度学习实践
【10月更文挑战第39天】本文旨在为初学者提供一条清晰的道路,从Python基础语法的掌握到深度学习领域的探索。我们将通过简明扼要的语言和实际代码示例,引导读者逐步构建起对人工智能技术的理解和应用能力。文章不仅涵盖Python编程的基础,还将深入探讨深度学习的核心概念、工具和实战技巧,帮助读者在AI的浪潮中找到自己的位置。
|
6天前
|
机器学习/深度学习 数据挖掘 Python
Python编程入门——从零开始构建你的第一个程序
【10月更文挑战第39天】本文将带你走进Python的世界,通过简单易懂的语言和实际的代码示例,让你快速掌握Python的基础语法。无论你是编程新手还是想学习新语言的老手,这篇文章都能为你提供有价值的信息。我们将从变量、数据类型、控制结构等基本概念入手,逐步过渡到函数、模块等高级特性,最后通过一个综合示例来巩固所学知识。让我们一起开启Python编程之旅吧!
|
6天前
|
存储 Python
Python编程入门:打造你的第一个程序
【10月更文挑战第39天】在数字时代的浪潮中,掌握编程技能如同掌握了一门新时代的语言。本文将引导你步入Python编程的奇妙世界,从零基础出发,一步步构建你的第一个程序。我们将探索编程的基本概念,通过简单示例理解变量、数据类型和控制结构,最终实现一个简单的猜数字游戏。这不仅是一段代码的旅程,更是逻辑思维和问题解决能力的锻炼之旅。准备好了吗?让我们开始吧!
|
8天前
|
设计模式 算法 搜索推荐
Python编程中的设计模式:优雅解决复杂问题的钥匙####
本文将探讨Python编程中几种核心设计模式的应用实例与优势,不涉及具体代码示例,而是聚焦于每种模式背后的设计理念、适用场景及其如何促进代码的可维护性和扩展性。通过理解这些设计模式,开发者可以更加高效地构建软件系统,实现代码复用,提升项目质量。 ####
|
8天前
|
并行计算 数据处理 调度
Python中的并发编程:探索多线程与多进程的奥秘####
本文深入探讨了Python中并发编程的两种主要方式——多线程与多进程,通过对比分析它们的工作原理、适用场景及性能差异,揭示了在不同应用需求下如何合理选择并发模型。文章首先简述了并发编程的基本概念,随后详细阐述了Python中多线程与多进程的实现机制,包括GIL(全局解释器锁)对多线程的影响以及多进程的独立内存空间特性。最后,通过实例演示了如何在Python项目中有效利用多线程和多进程提升程序性能。 ####
|
7天前
|
机器学习/深度学习 存储 算法
探索Python编程:从基础到高级应用
【10月更文挑战第38天】本文旨在引导读者从Python的基础知识出发,逐渐深入到高级编程概念。通过简明的语言和实际代码示例,我们将一起探索这门语言的魅力和潜力,理解它如何帮助解决现实问题,并启发我们思考编程在现代社会中的作用和意义。
|
7天前
|
机器学习/深度学习 数据挖掘 开发者
Python编程入门:理解基础语法与编写第一个程序
【10月更文挑战第37天】本文旨在为初学者提供Python编程的初步了解,通过简明的语言和直观的例子,引导读者掌握Python的基础语法,并完成一个简单的程序。我们将从变量、数据类型到控制结构,逐步展开讲解,确保即使是编程新手也能轻松跟上。文章末尾附有完整代码示例,供读者参考和实践。
|
8天前
|
人工智能 数据挖掘 程序员
Python编程入门:从零到英雄
【10月更文挑战第37天】本文将引导你走进Python编程的世界,无论你是初学者还是有一定基础的开发者,都能从中受益。我们将从最基础的语法开始讲解,逐步深入到更复杂的主题,如数据结构、面向对象编程和网络编程等。通过本文的学习,你将能够编写出自己的Python程序,实现各种功能。让我们一起踏上Python编程之旅吧!
|
9天前
|
数据采集 机器学习/深度学习 人工智能
Python编程入门:从基础到实战
【10月更文挑战第36天】本文将带你走进Python的世界,从基础语法出发,逐步深入到实际项目应用。我们将一起探索Python的简洁与强大,通过实例学习如何运用Python解决问题。无论你是编程新手还是希望扩展技能的老手,这篇文章都将为你提供有价值的指导和灵感。让我们一起开启Python编程之旅,用代码书写想法,创造可能。
|
10天前
|
Python
不容错过!Python中图的精妙表示与高效遍历策略,提升你的编程艺术感
本文介绍了Python中图的表示方法及遍历策略。图可通过邻接表或邻接矩阵表示,前者节省空间适合稀疏图,后者便于检查连接但占用更多空间。文章详细展示了邻接表和邻接矩阵的实现,并讲解了深度优先搜索(DFS)和广度优先搜索(BFS)的遍历方法,帮助读者掌握图的基本操作和应用技巧。
29 4