当前位置: 首页 > news >正文

Python编程 - 三器一包

目录

前言

一、迭代器

(一)基本概念

(二)迭代器和可迭代对象

(三)创建迭代器

(四)内置迭代器函数

(五)优点和局限性

二、生成器

(一)基本概念

(二)创建生成器

(三)生成器表达式

(四)生成器的优势

(五)使用生成器

(六)生成器的应用

(七)生成器和列表对比

三、装饰器

(一)装饰器的基本概念

(二)带参数的装饰器

(三)应用场景

(四)保持元数据

(五)总结

四、闭包

(一)简介

(二)闭包的结构

(三)工作原理

(四)应用场景

(五)注意事项

(六)闭包中修改外部变量

(七)总结

五、总结


前言

上篇文章将了python多态,类属性等知识,这篇文章了解一下python的三器一包:迭代器、生成器、装饰器和闭包


一、迭代器

Python的迭代器是一个重要的概念,特别是在处理序列数据和流数据时。迭代器是一种可以逐一遍历集合中所有元素的对象。

(一)基本概念

迭代器是实现了__iter__()__next__()方法的对象。

  • __iter__(): 这个方法返回迭代器对象本身。它在一个对象被迭代时会被自动调用,可以在循环或其他迭代环境中使用。
  • __next__(): 这个方法返回迭代中的下一个值。当序列遍历结束时,它会引发StopIteration异常,通知迭代终止。

(二)迭代器和可迭代对象

在Python中,有两种与迭代有关的对象类型:可迭代对象迭代器

  • 可迭代对象(Iterable):任何可以返回一个迭代器的对象都被称为可迭代对象。常见的可迭代对象包括列表、元组、字典、集合和字符串。可迭代对象实现了__iter__()方法。

  • 迭代器(Iterator):是一个有状态的对象,它会在调用__next__()时返回序列中的下一个值。迭代器对象实现了__iter__()__next__()方法。

(三)创建迭代器

可以通过实现__iter__()__next__()方法来手动创建一个迭代器。也可以通过iter()函数将一个可迭代对象转换为迭代器。

# 自定义迭代器示例
class MyIterator:def __init__(self, data):self.data = dataself.index = 0def __iter__(self):return selfdef __next__(self):if self.index < len(self.data):value = self.data[self.index]self.index += 1return valueelse:raise StopIteration# 使用迭代器
my_iter = MyIterator([1, 2, 3])
for item in my_iter:print(item)

(四)内置迭代器函数

python提供了一些内置函数来处理迭代器:

  • iter(): 返回一个迭代器对象。对于可迭代对象,iter()函数将其转换为迭代器。
  • next(): 通过调用迭代器的__next__()方法来获取下一个元素。如果没有元素可返回,则会引发StopIteration异常。
#示例
numbers = [1, 2, 3]
iterator = iter(numbers)
print(next(iterator))  # 输出: 1
print(next(iterator))  # 输出: 2
print(next(iterator))  # 输出: 3

(五)优点和局限性

  • 优点
    • 延迟计算:迭代器在需要时才生成元素,有助于节省内存。
    • 简化代码:通过迭代器,代码更简洁,容易处理无限序列。
  • 局限性
    • 一次性使用:迭代器一旦耗尽(遍历完),无法复用,必须重新创建。
    • 无法反向迭代:标准迭代器仅支持从前到后遍历,不能逆向。

二、生成器

生成器是一种特殊的迭代器,它能够在需要时生成值,从而使得处理大型数据集或流数据变得更加高效。生成器通过使用 yield 关键字创建,并且具有延迟计算的特性,即惰性求值,只有在迭代时才会生成值。下面详细介绍生成器的相关概念和使用方法。

(一)基本概念

生成器(Generator) 是一种函数,它在每次调用时都会生成一个值,并在其 yield 语句的地方暂停执行,下一次迭代从暂停的位置继续。与普通函数不同,生成器函数在执行完所有 yield 语句后会自动退出。

生成器的关键特性包括:

  • 惰性求值:生成器不会一次性生成所有值,而是按需生成,这对于处理大数据集或无限序列非常有用。
  • 状态保持:生成器函数在暂停时保持其执行状态(包括局部变量、指针等),并在下一次调用时继续执行。

(二)创建生成器

生成器通过定义一个包含 yield 语句的函数来创建。yield 会暂停函数的执行并返回一个值,当生成器的 __next__() 方法被调用时,函数会从暂停处继续执行。

# 生成器函数示例
def my_generator():print("First yield")yield 1print("Second yield")yield 2print("Third yield")yield 3# 使用生成器
gen = my_generator()
print(next(gen))  # 输出: First yield \n 1
print(next(gen))  # 输出: Second yield \n 2
print(next(gen))  # 输出: Third yield \n 3

(三)生成器表达式

python 提供了一种简洁的生成器定义方式,称为 生成器表达式。生成器表达式类似于列表推导式,但返回的是一个生成器对象,而不是一个列表。

# 生成器表达式示例
gen_expr = (x * x for x in range(5))for value in gen_expr:print(value)

在上面的示例中,gen_expr 是一个生成器,它在每次迭代时按需生成平方数。

(四)生成器的优势

生成器相比于普通函数和数据结构有许多优点:

  • 节省内存:生成器按需生成值,不会一次性将所有数据存储在内存中,非常适合处理大型或无限数据集。
  • 代码简洁:生成器表达式可以用一行代码创建生成器,减少了代码量。
  • 惰性求值:生成器只有在需要时才计算值,提高了效率,尤其是处理需要延迟计算的场景。

(五)使用生成器

除了使用 next() 函数来迭代生成器,还可以通过以下方式控制生成器:

  • send(value): 向生成器发送一个值,并暂停生成器的当前位置恢复执行。
  • close(): 终止生成器,生成器在下一次调用 __next__()send() 时会引发 StopIteration 异常。
  • throw(type, value=None, traceback=None): 在生成器中引发指定的异常,生成器可以捕获这个异常,并决定是继续还是终止。
def controlled_generator():while True:value = yieldif value is None:breakprint(f'Received: {value}')gen = controlled_generator()
next(gen)  # 初始化生成器
gen.send('Hello')  # 输出: Received: Hello
gen.send('World')  # 输出: Received: World
gen.close()  # 关闭生成器

(六)生成器的应用

生成器在Python中有许多实际应用,以下是一些常见的场景:

  • 数据流处理:生成器可以逐行读取文件,或按需处理数据流,减少内存消耗。
  • 延迟计算:当需要对大数据集进行计算但不想一次性加载时,生成器可以按需计算结果。
  • 管道处理:生成器可以连接在一起形成数据处理管道,每个生成器处理数据的一部分。

(七)生成器和列表对比

特性生成器列表
内存使用按需生成,节省内存一次性加载所有元素,占用大量内存
执行方式惰性求值,逐步生成立即求值,一次性生成所有元素
适用场景大数据集、流数据小数据集,频繁访问元素
代码复杂度简洁,适合管道处理简单明了,适合频繁访问

通过生成器,可以使Python程序在处理大规模数据时更加高效,特别是在内存受限或需要流式处理的场景下。生成器不仅提供了强大的功能,还保持了代码的简洁和可维护性。


三、装饰器

python的装饰器是一个强大的特性,允许你以优雅的方式修改函数或类的行为。装饰器可以用来插入额外的功能、修改函数行为,甚至是对函数进行包装而不直接修改其代码。

(一)装饰器的基本概念

装饰器是一个函数,接受另一个函数作为参数,返回一个新的函数。这个新的函数通常会在原函数的调用之前或之后执行额外的代码。装饰器本质上是一种“包装”机制,使得你可以在不修改原始函数代码的情况下,添加额外的功能。

示例:

def my_decorator(func):def wrapper():print("有些事情在调用方法之前发生")func()print("有些事情在调用方法之后发生")return wrapper@my_decorator
def say_hello():print("Hello!")say_hello()

在该示例中:

  1. my_decorator 是一个装饰器函数,它接受 func 作为参数。
  2. wrapper 函数在调用 func 之前和之后打印了一些信息。
  3. @my_decorator 是装饰器的应用方式,相当于 say_hello = my_decorator(say_hello)
  4. 当你调用 say_hello() 时,实际执行的是 wrapper 函数,其中包括了原始的 say_hello 函数的调用。

(二)带参数的装饰器

装饰器也可以接受参数。要实现带参数的装饰器,你需要创建一个嵌套的装饰器函数:

def repeat(num_times):def decorator(func):def wrapper(*args, **kwargs):for _ in range(num_times):func(*args, **kwargs)return wrapperreturn decorator@repeat(3)
def say_hello():print("Hello!")say_hello()

在这个例子中:

  1. repeat 是一个接受参数 num_times 的外部函数。
  2. decorator 是实际的装饰器函数。
  3. wrapper 是用来包装原函数的内部函数,它会根据 num_times 的值多次调用原函数。

(三)应用场景

装饰器在实际编程中非常有用,常见的应用场景包括:

  • 日志记录:记录函数的调用信息。
  • 权限检查:检查用户是否有权限调用某个函数。
  • 性能计时:测量函数的执行时间。
  • 缓存:缓存函数的返回值,以提高性能。
  • 输入验证:验证函数参数是否符合要求。

(四)保持元数据

使用装饰器时,通常会改变原函数的一些元数据,如名称和文档字符串。可以使用 functools.wraps 来保留这些元数据

示例:

from functools import wrapsdef my_decorator(func):@wraps(func)def wrapper(*args, **kwargs):print("调用函数之前被执行")result = func(*args, **kwargs)print("调用函数之后被执行")return resultreturn wrapper@my_decorator
def say_hello():"""Prints 'Hello!'"""print("Hello!")print(say_hello.__name__)  # 输出 'say_hello'
print(say_hello.__doc__)   # 输出 'Prints 'Hello!''

@wraps 装饰器帮助 wrapper 函数保留原函数的元数据(如名称和文档字符串)

(五)总结

装饰器是一种功能强大的工具,可以让你在不修改原始函数代码的情况下,添加额外的功能。理解装饰器的工作原理以及如何创建和使用它们,可以让你写出更加简洁、灵活和可维护的代码。


四、闭包

(一)简介

闭包是一个函数对象,它能记住并访问它所在的词法作用域中的变量,即使在该作用域已经结束时,仍然可以使用这些变量。换句话说,闭包是一种函数,可以捕获其外部环境的变量,使得这些变量即使超出了其正常的生命周期也能在函数内被访问。

闭包是由嵌套函数和自由变量构成的,闭包可以访问这些自由变量,即外部函数作用域中的变量,即使外部函数已经执行完毕。

(二)闭包的结构

一个闭包通常由三部分组成:

  1. 外部函数:定义了一个包含变量的作用域。
  2. 内部函数:嵌套在外部函数中并引用了外部函数的变量。
  3. 闭包环境:内部函数对外部函数作用域中变量的引用,使得这些变量在外部函数结束后仍然有效。

示例:

def outer_function(message):def inner_function():print(message)return inner_functionclosure_function = outer_function("Hello, Python!")
closure_function()  # 输出: Hello, Python!

在这个例子中:

  1. outer_function 是外部函数,它接受一个参数 message
  2. inner_function 是嵌套在 outer_function 中的内部函数,它使用了外部函数的变量 message
  3. outer_function 返回 inner_function 时,message 的值仍然被保留并可以在之后调用 closure_function() 时使用,即使 outer_function 已经执行完毕。

(三)工作原理

在上述示例中,虽然 outer_function 已经执行结束,但返回的 inner_function依然“记住”了 message 变量的值。这种机制就是闭包的重要特性,函数会保存它们所在的词法作用域中的变量,使得这些变量可以在函数执行后依然有效。python中的闭包通过函数对象的 __closure__ 属性来实现,这个属性包含了对外部作用域变量的引用。

示例:

def outer_function(message):def inner_function():print(message)return inner_functionclosure_function = outer_function("Hello, Python!")
print(closure_function.__closure__)  # 输出闭包中的自由变量
print(closure_function.__closure__[0].cell_contents)  # 输出自由变量的值 "Hello, Python!"

(四)应用场景

闭包在以下场景中非常有用:

  1. 数据隐藏:使用闭包可以隐藏数据,实现类似于面向对象编程中的私有变量的效果。
  2. 函数工厂:创建带有特定参数配置的函数,避免重复写相似逻辑。
  3. 回调函数:在异步编程或事件驱动编程中,闭包可以保持上下文,确保在执行回调时能访问正确的环境。
  4. 装饰器:装饰器的实现原理就依赖于闭包,允许在不改变函数定义的情况下扩展其功能。

(五)注意事项

闭包虽然强大,但也有一些需要注意的地方:

  1. 变量的作用域:闭包只能访问外部函数中的不可变变量,如果你想在内部函数中修改外部变量,必须使用 nonlocal 关键字。
  2. 可能导致内存泄漏:如果闭包引用的外部变量占用较多资源,可能导致内存泄漏,因为这些资源会一直存在,直到闭包被销毁。

(六)闭包中修改外部变量

通常情况下,闭包只能访问外部变量,但不能修改它们。如果需要修改外部函数中的变量,必须使用 nonlocal 关键字:

示例:

def outer_function():count = 0def inner_function():nonlocal count  # 使用nonlocal声明count += 1print(count)return inner_functionclosure_function = outer_function()
closure_function()  # 输出 1
closure_function()  # 输出 2

在这个例子中,nonlocal 允许 inner_function 修改 outer_function 中的 count 变量。

(七)总结

python的闭包是一种函数对象,它能够捕获并“记住”外部函数作用域中的自由变量,使得这些变量在外部函数执行结束后依然可用。闭包在许多高级编程场景中非常有用,比如装饰器、回调函数和数据隐藏等。


五、总结

该篇文章主要讲了python的三器一包,迭代器、生成器、装饰器和闭包,每个知识点都有各自的用途,相信大家都能通过这篇文章体会到其中的差异点,欢迎提出宝贵的意见和建议!!

相关文章:

Python编程 - 三器一包

目录 前言 一、迭代器 &#xff08;一&#xff09;基本概念 &#xff08;二&#xff09;迭代器和可迭代对象 &#xff08;三&#xff09;创建迭代器 &#xff08;四&#xff09;内置迭代器函数 &#xff08;五&#xff09;优点和局限性 二、生成器 &#xff08;一&…...

InternVL 多模态模型部署微调实践

友情链接 该文档参考InternVL垂直领域场景微调实践而写成&#xff0c;感谢社区同学法律人的文档。 写在前面&#xff08;什么是InternVL&#xff09; InternVL 是一种用于多模态任务的深度学习模型&#xff0c;旨在处理和理解多种类型的数据输入&#xff0c;如图像和文本。它…...

Ruby Dir 类和方法

Ruby Dir 类和方法 Ruby 中的 Dir 类提供了用于处理目录的各种方法。这些方法允许您列出目录内容、更改当前工作目录、创建和删除目录等。本文将详细介绍 Dir 类的常用方法&#xff0c;并通过示例展示如何使用它们。 目录 Dir 类的简介常用方法 Dir.chdirDir.childrenDir.de…...

C++STL~~deque

文章目录 deque的概念deque的使用deque的练习总结 deque的概念 deque(双端队列)&#xff1a;是一种序列容器、是一种双开口的"连续"空间的数据结构&#xff0c;双开口的含义是&#xff1a;可以在头尾两端进行插入和删除操作&#xff0c;且时间复杂度为O(1)&#xff…...

SpringCloud的学习,Consul服务注册与发现、分布式配置,以及 服务调用和负载均衡

介绍 Consul 是一套开源的分布式服务发现和配置管理系统&#xff0c;由 HashiCorp 公司用 Go 语言开发。 提供了微服务系统中的服务治理、配置中心、控制总线等功能。这些功能中的每一个都可以根据需要单独使用&#xff0c;也可以一起使用以构建全方位的服务网格&#xff0c;…...

闯关leetcode——26. Remove Duplicates from Sorted Array

大纲 题目地址内容 解题代码地址 题目 地址 https://leetcode.com/problems/remove-duplicates-from-sorted-array/description/ 内容 Given an integer array nums sorted in non-decreasing order, remove the duplicates in-place such that each unique element appear…...

基于A2C与超启发式的航天器星载自主任务规划算法-笔记

1. Actor-Critic 模块 主要文件&#xff1a;AC.py, PolicyNet.py, ValueNet.py作用&#xff1a;该模块实现了 A2C&#xff08;Advantage Actor-Critic&#xff09;强化学习算法。其中&#xff0c;ActorCritic 类是核心&#xff0c;它同时管理策略网络&#xff08;Actor&#x…...

[机器学习]决策树

1 决策树简介 2 信息熵 3 ID3决策树 3.1 决策树构建流程 3.2 决策树案例 4 C4.5决策树 5 CART决策树&#xff08;分类&回归&#xff09; 6 泰坦尼克号生存预测案例 import pandas as pd from sklearn.model_selection import train_test_split from sklearn.tree import …...

CentOS7更换阿里云yum更新源

目前CentOS内置的更新安装源经常报错无法更新&#xff0c;或者速度不够理想&#xff0c;这个时候更换国内的镜像源就是一个不错的选择。 备份内置更新源 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup 下载阿里云repo源&#xff08;需要系统…...

算法参数对拥塞控制的影响

来看看参数对公平收敛的影响。仅假象一下就知道应该是个加权公平&#xff0c;但事实如何&#xff0c;还是要具体看一下。 首先看 aimd&#xff0c;标准的 reno 算法是每 round 之后 cwnd 加 1&#xff0c;但如果有些流加 1&#xff0c;有些流加 2&#xff0c;会如何&#xff1…...

Go websocket

Go 中的 gorilla/websocket 是一个常用且高效的 WebSocket 实现库&#xff0c;可以帮助你轻松地在 Web 应用中实现实时通信。学习 gorilla/websocket 的基本用法包括建立 WebSocket 连接、发送和接收消息、处理错误、以及在实际场景中的使用。以下是关于 gorilla/websocket 的学…...

C# 委托与事件 观察者模式

委托与事件是一种观察者模式。 什么是委托与事件 在c#中&#xff0c;委托类似于代理&#xff0c;也跟其它语言的函数指针、回调函数等相似&#xff0c;但委托是类型安全和可靠的。声明自定义委托时&#xff0c;加上delegate关键字&#xff0c;委托定义类似于接口。 事件是特殊…...

K8S - 用service account 登陆kubectl

刚安装好k8s时 我就可以用kubectl 在master server里管理k8s的资源。 这时我们是感觉不到 k8s的用户和权限管理存在的&#xff0c; 但是其实用户的配置都在kubeclt 的配置文件中 /etc/kubernetes/admin.conf 中 我们可以用下命令来查看当前正在用的帐号 rootk8s-master:~/.d…...

Redis 持久化机制详解

引言 Redis 是一款基于内存的高性能键值存储系统&#xff0c;为了在数据丢失时能快速恢复&#xff0c;Redis 提供了多种持久化机制。这些持久化机制可以将内存中的数据存储到磁盘上&#xff0c;确保即使系统重启或宕机后也能恢复数据。Redis 支持两种主要的持久化方式&#xf…...

小阿轩yx-案例:Zabbix监控kubernetes云原生环境

小阿轩yx-案例&#xff1a;Zabbix监控kubernetes云原生环境 前言 传统监控的本质 就是收集、分析和使用信息来观察一段时间内监控对象的运行进度&#xff0c;并且进行相应的决策管理的过程&#xff0c;监控侧重于观察特定指标。 随着云原生时代的到来 我们对监控的功能提出…...

量化交易的个人见解

程序化交易在国内兴起有些年数了&#xff0c;个人以为&#xff0c;程序化交易与量化投资的关系&#xff0c;在于两者侧重点有差别。程序化交易侧重于下单的动作是机器自动执行的&#xff0c;量化投资则侧重于投资分析的过程是通过一个量化模型来实现的&#xff0c;所以量化投资…...

Java集合(一)

目录 Java集合&#xff08;一&#xff09; 集合介绍 单列集合分类 Collection接口 创建Collection实现类对象 常用方法 迭代器 基本使用 迭代器的执行过程 迭代器底层原理 集合中的并发修改异常及原因分析 List接口 ArrayList类 介绍 常用方法 遍历集合 Array…...

车载软件架构 --- SOA设计与应用(下)

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一眼都是你的不对。非必要不费力证明自己,无利益不试图说服别人,是精神上的节…...

网络原理 IP协议与以太网协议

博主主页: 码农派大星. 数据结构专栏:Java数据结构 数据库专栏:MySQL数据库 JavaEE专栏:JavaEE 关注博主带你了解更多数据结构知识 目录 1.网络层 IP协议 1.IP协议格式 2.地址管理 2.1 IP地址 2.2 解决IP地址不够用的问题 2.3NAT网络地址转换 2.4网段划分 3.路由选择…...

k8s的安装

k8s的安装 1.创建主机&#xff0c;设置ip,hostname&#xff0c;关闭firewalld,selinux,NetworkManager 编号主机名称ip1k8s-master192.168.118.662k8s-node01192.168.118.773k8s-node02192.168.118.88 2.设置主机之间的ssh免密 [rootk8s-master ~]# ssh-keygen [rootk8s-ma…...

label-studio的使用教程(导入本地路径)

文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

ios苹果系统,js 滑动屏幕、锚定无效

现象&#xff1a;window.addEventListener监听touch无效&#xff0c;划不动屏幕&#xff0c;但是代码逻辑都有执行到。 scrollIntoView也无效。 原因&#xff1a;这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作&#xff0c;从而会影响…...

网络编程(UDP编程)

思维导图 UDP基础编程&#xff08;单播&#xff09; 1.流程图 服务器&#xff1a;短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...

CMake控制VS2022项目文件分组

我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...

稳定币的深度剖析与展望

一、引言 在当今数字化浪潮席卷全球的时代&#xff0c;加密货币作为一种新兴的金融现象&#xff0c;正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而&#xff0c;加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下&#xff0c;稳定…...

Python+ZeroMQ实战:智能车辆状态监控与模拟模式自动切换

目录 关键点 技术实现1 技术实现2 摘要&#xff1a; 本文将介绍如何利用Python和ZeroMQ消息队列构建一个智能车辆状态监控系统。系统能够根据时间策略自动切换驾驶模式&#xff08;自动驾驶、人工驾驶、远程驾驶、主动安全&#xff09;&#xff0c;并通过实时消息推送更新车…...

Spring AI Chat Memory 实战指南:Local 与 JDBC 存储集成

一个面向 Java 开发者的 Sring-Ai 示例工程项目&#xff0c;该项目是一个 Spring AI 快速入门的样例工程项目&#xff0c;旨在通过一些小的案例展示 Spring AI 框架的核心功能和使用方法。 项目采用模块化设计&#xff0c;每个模块都专注于特定的功能领域&#xff0c;便于学习和…...

Mac flutter环境搭建

一、下载flutter sdk 制作 Android 应用 | Flutter 中文文档 - Flutter 中文开发者网站 - Flutter 1、查看mac电脑处理器选择sdk 2、解压 unzip ~/Downloads/flutter_macos_arm64_3.32.2-stable.zip \ -d ~/development/ 3、添加环境变量 命令行打开配置环境变量文件 ope…...

用 Rust 重写 Linux 内核模块实战:迈向安全内核的新篇章

用 Rust 重写 Linux 内核模块实战&#xff1a;迈向安全内核的新篇章 ​​摘要&#xff1a;​​ 操作系统内核的安全性、稳定性至关重要。传统 Linux 内核模块开发长期依赖于 C 语言&#xff0c;受限于 C 语言本身的内存安全和并发安全问题&#xff0c;开发复杂模块极易引入难以…...

Linux基础开发工具——vim工具

文章目录 vim工具什么是vimvim的多模式和使用vim的基础模式vim的三种基础模式三种模式的初步了解 常用模式的详细讲解插入模式命令模式模式转化光标的移动文本的编辑 底行模式替换模式视图模式总结 使用vim的小技巧vim的配置(了解) vim工具 本文章仍然是继续讲解Linux系统下的…...