Python-VBA函数之旅-classmethod函数

目录

一、装饰器的定义:

二、装饰器类型:

三、装饰器的主要用途:

四、classmethod常用场景:

1、classmethod函数:

1-1、Python:

1-2、VBA:

2、相关文章:


        classmethod是 Python 中的一个装饰器,用于表示一个方法是类级别的方法,而不是实例级别的方法。使用 `@classmethod` 装饰器的方法接收的第一个参数是类本身(通常命名为 `cls`,只要不与Python中相关的内置信息相冲突即可,一般没有硬性规定,但要注意与实例对象的区分开,以免混淆,难于理解,且不利于后期代码维护),而不是实例对象(通常命名为 `self `)。

一、装饰器的定义:

        装饰器(Decorator)是一种在不修改原始函数或类代码的情况下,通过包装函数或类来扩展其功能的技术。它基于Python的函数式编程思想,可以更好地实现代码的重用性和可读性,避免了代码重复而造成的冗长和混乱。

装饰器通常是一个函数,它接受一个函数或类作为参数,并返回一个新的函数或类。这个新函数或类通常会在调用原始函数或类之前或之后执行一些额外的逻辑。装饰器可以用于添加日志记录、性能分析、输入验证、缓存处理等功能。

在Python中,装饰器使用`@`符号紧跟在函数或类定义的上方,表示将函数或类装饰为另一个函数或类。装饰器函数可以接受任意数量的参数,并返回一个新的函数或类。

装饰器按照功能可以分为函数装饰器和类装饰器。函数装饰器应用于函数,而类装饰器应用于类。使用类装饰器还可以依靠类内部的`__call__`方法,当使用`@`形式将装饰器附加到函数或类上时,就会调用此方法。

        总的来说,装饰器(Decorator)是解决特定编程问题的一种有效设计,可以抽离出大量与函数或类功能本身无关的雷同代码,提高代码的可读性和可维护性。

二、装饰器类型:

        Python中的装饰器种类非常丰富,涵盖了各种不同的功能和应用场景。以下是一些常见的Python装饰器类型:

1、函数装饰器:
1-1、@staticmethod:将方法转换为静态方法,使其不依赖于类实例,而是直接在类上调用。
1-2、@classmethod:将方法转换为类方法,该方法接收类本身作为第一个参数,而不是实例对象。
1-3、@property:将一个方法转换为属性,允许像访问数据属性一样调用方法。
1-4、@functools.lru_cache:实现最近最少使用(LRU)缓存,用于缓存函数结果。
1-5、@wraps:保留被装饰函数的元数据,如函数名、文档字符串等。

2、类装饰器:
2-1、类装饰器通常用于修改类定义或创建新的类。
2-2、它们可以动态地添加、修改或删除类属性或方法。

3、通用功能装饰器:
3-1、@timer:测量函数的执行时间,用于性能分析。
3-2、@memoize:缓存函数结果,避免重复计算。
3-3、@logger:记录函数或类的调用日志。
3-4、@repeat:重复执行函数指定的次数。
3-5、@singleton:确保类只有一个实例。
3-6、@contextmanager:将生成器函数转换为上下文管理器,用于简化资源管理(如文件打开和关闭)。

4、异步装饰器:
4-1、@asyncio.coroutine:在Python 3.7之前的版本中,用于标识异步函数。
4-2、@sync_to_async/@async_to_sync:在Django的异步支持中,用于将同步函数转换为异步函数,或将异步函数转换为同步函数。

5、权限和安全性装饰器:
5-1、这类装饰器通常用于验证用户权限、检查API密钥等,以确保只有授权用户才能访问特定的函数或类。

6、API路由装饰器:
6-1、在web框架(如Flask、FastAPI)中,装饰器常用于定义路由和处理HTTP请求。

7、数据验证和序列化装饰器:
7-1、用于在函数或方法调用前后验证输入数据或序列化输出数据。

8、自定义装饰器:
8-1、根据特定需求,你可以创建自己的装饰器来实现任何你想要的功能。

        总之,虽然装饰器提供了很大的灵活性和便利性,但过度使用或不当使用可能会导致代码难以理解和维护。因此,在使用装饰器时,建议仔细考虑其必要性和适用性,并遵循良好的编程实践。

三、装饰器的主要用途:

        装饰器(Decorator)是一种强大的Python编程工具,它允许在不修改原始函数或类代码的情况下,通过包装函数或类来扩展其功能。以下是装饰器的一些主要用途:

1、功能扩展:装饰器的主要作用之一是扩展函数或类的功能。通过在函数调用前后添加额外的逻辑,装饰器可以轻松地增加诸如日志记录、性能分析、输入验证、缓存等功能,而无需修改原始函数的代码。

2、日志记录:装饰器可以记录函数或方法的调用日志,包括参数、返回值等信息。这对于调试和追踪代码的执行过程非常有用,可以帮助开发者更好地理解程序的运行流程和性能瓶颈。

3、性能分析:通过装饰器,可以测量函数或方法的执行时间,从而进行性能分析。这对于优化代码、提高程序运行效率非常有帮助。

4、权限控制:装饰器可以用于验证用户权限,限制某些函数或类的访问权限。例如,可以通过装饰器实现基于角色的访问控制,确保只有具有特定角色的用户才能调用特定的函数或方法。

5、缓存数据:装饰器可以用于缓存函数的计算结果,避免重复计算。这对于计算密集型任务或频繁调用的函数非常有用,可以显著提高代码的执行效率。

6、代码重用和简化:装饰器可以将一些通用的、重复的代码逻辑抽离出来,使得原始函数或类的代码更加简洁和清晰。同时,由于装饰器本身也是函数或类,因此可以很容易地实现代码的重用。

7、动态修改行为:装饰器允许在运行时动态地修改对象的行为,而无需修改原始对象的代码。这使得代码更加灵活和可扩展,可以更容易地适应不同的需求和场景。

        总之,虽然装饰器非常强大和灵活,但过度使用可能会导致代码变得复杂和难以维护。因此,在使用装饰器时,需要权衡其优点和缺点,并根据项目的具体需求来合理使用。

四、classmethod常用场景:

        在Python中,classmethod函数的应用场景广泛,它允许我们编写与类本身关联而非与特定实例关联的方法。常用场景如下:

1、工厂方法:用于创建并返回类的实例,通常根据传入的参数以不同的方式初始化实例。

1-1、优点:

1-1-1、代码复用:工厂方法允许你使用相同的逻辑来创建类的多个实例,这有助于减少代码冗余并提高代码的可读性。

1-1-2、灵活性:工厂方法可以根据不同的输入参数返回不同的类实例,这使得代码更加灵活和可扩展。

1-1-3、封装:工厂方法将创建实例的逻辑封装在类中,使得外部代码无需知道创建实例的具体细节。这有助于隐藏实现细节,并使得API更加简洁和清晰。

1-1-4、解耦:通过将创建实例的逻辑与类的其他逻辑分开,工厂方法有助于降低代码的耦合度,使得代码更容易维护和测试。

1-2、缺点:

1-2-1、学习成本:对于初学者来说,理解类方法和工厂方法的概念可能需要一些时间。这可能会增加学习曲线,使得代码更难以理解。

1-2-2、过度使用可能导致代码复杂性:虽然工厂方法在某些情况下非常有用,但过度使用可能会导致代码变得复杂和难以维护。每个工厂方法都需要编写和维护,这可能会增加开发成本。

1-2-3、可能隐藏错误:由于工厂方法封装了创建实例的逻辑,如果这个逻辑出现问题,那么错误可能会更难被发现和调试。这要求开发者在编写工厂方法时更加谨慎,并进行充分的测试。

2、修改类级别的状态:有时你可能需要在不创建类实例的情况下修改类的状态。classmethod允许你直接通过类来访问和修改类变量。

2-1、优点:

2-1-1、集中管理:类级别的状态通常用于存储与类本身相关的信息,而不是与特定实例相关的信息。通过classmethod修改类级别的状态,可以将这些操作集中在一个地方,使得代码更加整洁和易于维护。

2-1-2、共享状态:类级别的状态在所有实例之间是共享的。这意味着,通过classmethod修改类级别的状态,可以影响所有实例的行为。这在某些情况下是非常有用的,比如当你想在多个实例之间共享某些信息时。

2-1-3、简化访问:使用classmethod可以方便地访问和修改类级别的状态,而无需创建类的实例。这在某些情况下可以简化代码,并减少不必要的对象创建。

2-2、缺点:

2-2-1、全局状态:修改类级别的状态相当于修改全局状态,这可能导致代码更难理解和测试。全局状态通常被认为是编程中的一个坏味道,因为它增加了代码的耦合度,使得不同部分的代码可能无意中相互影响。

2-2-2、线程安全问题:在多线程环境中,如果多个线程同时修改类级别的状态,可能会导致竞态条件和数据不一致的问题。因此,在使用classmethod修改类级别的状态时,需要特别注意线程安全的问题。

2-2-3、隐藏依赖:通过classmethod修改类级别的状态可能会隐藏代码之间的依赖关系。其他代码可能依赖于这些类级别的状态,而如果不了解这一点,就可能导致难以调试的问题。

2-2-4、难以扩展:如果类级别的状态变得复杂或需要频繁修改,使用classmethod可能会使代码难以扩展和维护。在这种情况下,可能需要考虑使用其他设计模式或架构来管理状态。

3、替代构造函数:有时,我们可能希望提供多个方式来创建类的实例,每个方式可能对应不同的初始化逻辑。classmethod可以作为替代构造函数,提供不同的初始化路径。

3-1、优点:

3-1-1、灵活性:使用classmethod作为工厂方法可以提供更灵活的实例创建机制。工厂方法可以根据不同的输入参数返回不同类型的实例,或者根据某些条件执行额外的初始化逻辑。

3-1-2、封装:工厂方法可以将实例创建的细节封装在类内部,外部代码无需知道创建实例的具体细节。这有助于隐藏实现细节,并提供一个简洁的API接口。

3-1-3、解耦:通过将实例创建的逻辑与类的其他逻辑分开,工厂方法有助于降低代码的耦合度。这使得代码更容易维护和测试,特别是在需要替换或扩展实例创建逻辑的情况下。

3-2、缺点:

3-2-1、学习成本:对于不熟悉工厂模式的开发者来说,使用classmethod作为工厂方法可能需要一些时间来理解和适应。这可能会增加学习曲线,并使得代码更难以阅读和理解。

3-2-2、可能增加复杂性:过度使用工厂方法可能会增加代码的复杂性。每个工厂方法都需要编写和维护,这可能会增加开发成本。此外,如果工厂方法的逻辑过于复杂,可能会导致代码难以理解和维护。

3-2-3、隐藏构造函数:使用工厂方法替代构造函数可能会隐藏类的构造函数本身。这可能会导致其他开发者不清楚如何直接创建类的实例,或者忘记了类的构造函数的存在。这可能会降低代码的可读性和可维护性。

4、实现单例模式:单例模式确保一个类只有一个实例,并提供一个全局访问点来获取该实例。classmethod在实现单例模式时非常有用。

5、注册子类或插件:当需要动态地注册或管理子类或插件时,classmethod可以用来实现这种功能。

1、classmethod函数:
1-1、Python:
# 1.函数:classmethod
# 2.功能:将一个方法转变为类方法
# 3.语法:
# class MyClass:
#     @classmethod
#     def my_classmethod(cls, *args, **kwargs):
#         # 方法体
#         pass
# 4.参数:
# 4-1、cls:表示类本身,只要不与python相关内置信息相冲突,没有硬性规定,只是为了区别实例中的“self”而取了类class前3个字母命名
# 4-2、可变参数(Variable-length Arguments):
# 4-2-1、*args(非关键字可变参数):使用*args可以在函数定义中接收任意数量的非关键字参数,这些参数在函数内部作为元组处理
# 4-2-2、**kwargs(关键字可变参数):使用**kwargs可以在函数定义中接收任意数量的关键字参数,这些参数在函数内部作为字典处理
# 5.返回值:返回值可以是任何类型的对象,包括None、整数、字符串、列表、字典等
# 6.说明:
# 6-1、接收的第一个参数是类本身:在类方法内部,你可以通过该参数来访问或修改类级别的属性或方法。
#      通常,这个参数被命名为`cls`,以区别于实例方法的`self`参数。
# 6-2、不需要类的实例来调用:类方法可以直接通过类名来调用,而不需要先创建类的实例。
#      这使得类方法非常适合作为工厂方法或用于修改类级别的状态。
# 6-3、用途:类方法常用于以下场景:
# 6-3-1、工厂方法:创建并返回类的实例,可以根据需要定制实例的初始化过程
# 6-3-2、修改类级别的状态:设置或获取与类本身关联的属性,而不是与特定实例关联的属性
# 6-3-3、替代构造函数:提供不同的方式来创建类的实例
# 6-4、与静态方法的区别:静态方法(使用@staticmethod装饰器)既不接收`self`也不接收`cls`作为第一个参数。
#      它们是完全独立的函数,只是作为类的一部分存在。静态方法通常用于组织代码或提供与类相关的实用功能。
# 7.示例:
# 应用1:工厂方法
# 定义Shape基类,它有一个抽象方法area,子类需要实现这个方法
class Shape:
    def area(self):
        raise NotImplementedError("子类必须实现这个方法!")
    # 定义类方法create_shape,用于根据shape_type创建对应的形状对象
    @classmethod
    def create_shape(cls, shape_type, *args, **kwargs):
        # 根据shape_type判断创建哪种形状对象
        if shape_type == "circle":
            return Circle(*args, **kwargs)
        elif shape_type == "rectangle":
            return Rectangle(*args, **kwargs)
        else:
            # 如果shape_type无效,则抛出异常
            raise ValueError(f"无效的形状类型: {shape_type}")
# 定义Circle类,继承自Shape
class Circle(Shape):
    # 初始化方法,接收半径参数
    def __init__(self, radius):
        self.radius = radius
    # 实现area方法,计算圆的面积
    def area(self):
        return 3.14 * self.radius ** 2
# 定义Rectangle类,继承自Shape
class Rectangle(Shape):
    # 初始化方法,接收长度和宽度参数
    def __init__(self, length, width):
        self.length = length
        self.width = width
    # 实现area方法,计算矩形的面积
    def area(self):
        return self.length * self.width
# 主函数入口
if __name__ == '__main__':
    # 使用工厂方法create_shape创建Circle对象
    circle = Shape.create_shape("circle", radius=5)
    # 使用工厂方法create_shape创建Rectangle对象
    rectangle = Shape.create_shape("rectangle", length=10, width=5)
    # 输出圆的面积
    print(circle.area())
    # 输出矩形的面积
    print(rectangle.area())
# 78.5
# 50

# 应用2:修改类级别的状态
class Counter:
    # 初始化类变量count为0,用于记录计数值
    count = 0
    # 定义一个类方法,用于增加计数器
    @classmethod
    def increment_count(cls):
        cls.count += 1
    # 定义一个类方法,用于获取当前的计数值
    @classmethod
    def get_count(cls):
        return cls.count
# 主程序入口
if __name__ == '__main__':
    # 调用类方法increment_count增加计数器
    Counter.increment_count()
    # 打印当前的计数值
    print(Counter.get_count())
    # 再次调用类方法increment_count增加计数器
    Counter.increment_count()
    # 打印当前的计数值
    print(Counter.get_count())
    # 创建Counter类的两个实例
    c1 = Counter()
    c2 = Counter()
    # 分别通过实例调用类方法get_count获取并打印计数值
    # 注意:这里虽然是通过实例调用的类方法,但实际上方法内部操作的是类变量,因此所有实例共享同一个计数值
    print(c1.get_count())
    print(c2.get_count())
# 1
# 2
# 2
# 2

# 应用3:替代构造函数
class Person:
    def __init__(self, name, age):
        # 初始化方法,用于创建Person对象时设置name和age属性
        self.name = name
        # 使用下划线前缀表示_age为私有属性,通常用于表示该属性不应直接通过对象访问
        self._age = age
    @classmethod
    def from_string(cls, person_str):
        """
        从字符串中解析并创建Person对象
        Args:
            person_str(str): 包含姓名和年龄的字符串,格式为"姓名,年龄"
        Returns:
            Person: 创建的Person对象
        """
        # 使用split方法按照逗号分隔字符串,得到姓名和年龄的列表
        name, age_str = person_str.strip().split(',')
        # 将年龄字符串转换为整数类型
        age = int(age_str.strip())
        # 使用类方法创建的类(cls)来实例化Person对象,并返回
        return cls(name, age)
    @property
    def age(self):
        # 使用property装饰器定义age属性的getter方法,使得可以像访问数据属性一样访问_age
        return self._age
# 主函数
if __name__ == '__main__':
    # 创建名为"Myelsa",年龄为18的Person对象
    person1 = Person("Myelsa", 18)
    # 创建一个包含姓名和年龄的字符串
    person_str = "Jimmy, 15"
    # 使用from_string类方法从字符串中解析并创建Person对象
    person2 = Person.from_string(person_str)
    # 打印person1的姓名和年龄
    print(person1.name, person1.age)
    # 打印person2的姓名和年龄
    print(person2.name, person2.age)
# Myelsa 18
# Jimmy 15

# 应用4:实现单例模式
class Singleton:
    # 静态类变量,用于存储单例实例
    _instance = None
    # 重写__new__方法,用于控制实例的创建
    def __new__(cls, *args, **kwargs):
        # 检查是否已经有实例存在
        if cls._instance is None:
            # 如果没有实例,则创建新实例
            cls._instance = super().__new__(cls)
        # 无论是否已有实例,都返回已存在的实例
        return cls._instance
    # 类方法,用于获取单例实例
    @classmethod
    def get_instance(cls):
        # 检查是否已经有实例存在
        if cls._instance is None:
            # 如果没有实例,则通过调用类本身来创建实例
            # 注意:这里假设__new__方法已被正确实现来确保单例
            cls._instance = cls.__new__(cls)
        # 返回已存在的实例
        return cls._instance
# 主程序入口
if __name__ == "__main__":
    # 调用get_instance方法获取单例实例
    instance1 = Singleton.get_instance()
    # 直接通过类调用实例化,由于__new__方法已重写,这里也会返回已存在的实例
    instance2 = Singleton()
    # 打印instance1和instance2是否是同一个对象
    print(instance1 is instance2)  # 输出: True,说明两个引用指向的是同一个对象
# True

# 应用5:注册子类或插件
class PluginBase:
    # 类级别的字典,用于存储注册的插件(子类)
    registered_plugins = {}
    @classmethod
    def register_plugin(cls, plugin_cls):
        """
        注册插件(子类)到registered_plugins字典中
        :param plugin_cls: 要注册的插件类
        """
        # 假设每个插件都有一个唯一的名称属性
        plugin_name = getattr(plugin_cls, 'name', plugin_cls.__name__)
        if plugin_name in cls.registered_plugins:
            raise ValueError(f"Plugin {plugin_name} is already registered.")
        cls.registered_plugins[plugin_name] = plugin_cls
    @classmethod
    def get_plugin(cls, plugin_name):
        """
        根据插件名称获取插件类
        :param plugin_name: 插件名称
        :return: 插件类,如果未找到则返回None
        """
        return cls.registered_plugins.get(plugin_name)
# 插件类
class PluginA(PluginBase):
    name = 'PluginA'
class PluginB(PluginBase):
    name = 'PluginB'
if __name__ == '__main__':
    # 注册插件
    PluginBase.register_plugin(PluginA)
    PluginBase.register_plugin(PluginB)
    # 获取并打印注册的插件
    for name, plugin_cls in PluginBase.registered_plugins.items():
        print(f"Registered plugin: {name} -> {plugin_cls}")
    # 根据名称获取插件类
    plugin_a_cls = PluginBase.get_plugin('PluginA')
    print(f"PluginA class: {plugin_a_cls}")
# Registered plugin: PluginA -> <class '__main__.PluginA'>
# Registered plugin: PluginB -> <class '__main__.PluginB'>
# PluginA class: <class '__main__.PluginA'>
1-2、VBA:
VBA很难模拟类似场景,略。
2、相关文章:

2-1、Python-VBA函数之旅-callable()函数

2-2、Python-VBA函数之旅-chr()函数 

2-3、Python-VBA函数之旅-compile()函数 

Python算法之旅:Algorithm

Python函数之旅:Functions​​​​​​​ 

个人主页:非风V非雨-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/548491.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MySQL查询重复数据获取最新数据

方法一&#xff1a; 1055 - Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column ‘se_jck的博客-CSDN博客 这个错误是由于 MySQL 的新版本中默认开启了ONLY_FULL_GROUP_BY模式&#xff0c;即在 GROUP BY 语句中的 SELECT 列表中&…

数据湖技术选型——Flink+Paimon 方向

文章目录 前言Apache Iceberg存储索引metadataFormat V2小文件 Delta LakeApache Hudi存储索引COWMOR元数据表 Apache PaimonLSMTagconsumerChangelogPartial Update 前言 对比读写性能和对流批一体的支持情况&#xff0c;建议选择Apache Paimon截止2024年1月12日数据湖四大开…

【LAMMPS学习】八、基础知识(2.5)恒压器

8. 基础知识 此部分描述了如何使用 LAMMPS 为用户和开发人员执行各种任务。术语表页面还列出了 MD 术语&#xff0c;以及相应 LAMMPS 手册页的链接。 LAMMPS 源代码分发的 examples 目录中包含的示例输入脚本以及示例脚本页面上突出显示的示例输入脚本还展示了如何设置和运行各…

基于混合博弈的配电网与多综合能源微网优化运行

该文研究了同一配电网下的多个综合能源微网 (integrated energy microgrids&#xff0c;IEM)的协同管理问题&#xff0c;旨在通 过配电网运营商(distribution system operator&#xff0c;DSO)制定电能 价格以协调 IEM 联盟的机组调度、需求响应和成员间的点 对点(peer-to-peer…

使用Scrapy选择器提取豆瓣电影信息,并用正则表达式从介绍详情中获取指定信息

本文同步更新于博主个人博客&#xff1a;blog.buzzchat.top 一、Scrapy框架 1. 介绍 在当今数字化的时代&#xff0c;数据是一种宝贵的资源&#xff0c;而网络爬虫&#xff08;Web Scraping&#xff09;则是获取网络数据的重要工具之一。而在 Python 生态系统中&#xff0c;S…

Oracle和PG数据库临时表的差异,PG数据库如何删除临时表

现实的开发过程中使用 PG 数据库删除临时表发现如下报错&#xff0c;提示表 xxx 不存在&#xff1a; 问题原因&#xff1a; 调用删除语句&#xff0c;但是临时表不存在了。 解决方案&#xff1a; PG下用下面的方式来删除临时表或不进行删除&#xff08;会话级临时表会自动删除…

线性表的链式存储

文章目录 前言一、概念及特点二、链表术语及分类三、单链表1.特点2.C语言实现3.头结点作用4.基本操作的具体实现 总结 前言 T_T此专栏用于记录数据结构及算法的&#xff08;痛苦&#xff09;学习历程&#xff0c;便于日后复习&#xff08;这种事情不要啊&#xff09;。所用教材…

Cannot access ‘androidx.activity.FullyDrawnReporterOwner‘

Android Studio新建项目就报错&#xff1a; Cannot access ‘androidx.activity.FullyDrawnReporterOwner’ which is a supertype of ‘cn.dazhou.osddemo.MainActivity’. Check your module classpath for missing or conflicting dependencies 整个类都报错了。本来原来一直…

文献学习-37-动态场景中任意形状针的单目 3D 位姿估计:一种高效的视觉学习和几何建模方法

On the Monocular 3D Pose Estimation for Arbitrary Shaped Needle in Dynamic Scenes: An Efficient Visual Learning and Geometry Modeling Approach Authors: Bin Li,† , Student Member, IEEE, Bo Lu,† , Member, IEEE, Hongbin Lin, Yaxiang Wang, Fangxun Zhong, Me…

使用arthas查看java项目resources目录下面的文件内容

有一次在测试环境想看resources下面的mapper文件内容&#xff08;代码执行和预期不一致&#xff0c;所以想排查一下是不是打上去的包有问题&#xff0c;没有通过下载jar的方式解压查看&#xff09;&#xff0c;然后想到了使用arthas来弄&#xff0c;这里记录一下怎么个查看法。…

【Textin.com】智能文档处理系列 - 电子文档解析技术全格式解析

一、引言 在当今的数字化时代&#xff0c;电子文档已成为信息存储和交流的基石。从简单的文本文件到复杂的演示文档&#xff0c;各种格式的电子文档承载着丰富的知识与信息&#xff0c;支撑着教育、科研、商业和日常生活的各个方面。随着信息量的爆炸性增长&#xff0c;如何高效…

listpack

目录 为什么有listpack? listpack结构 listpack的节点entry 长度length encoding编码方式 listpack的API 1.创建listpack 2.遍历操作 正向遍历 反向遍历 3.查找元素 4.插入/替换/删除元素 总结 为什么有listpack? ziplist是存储在连续内存空间&#xff0c;节省…

Spring Boot 2.x 将 logback 1.2.x 升级至 1.3.x

场景 安全部门针对代码进行漏洞扫描时&#xff0c;发现 logback-core 和 logback-classic 都属于 1.2.x 版本&#xff0c;这个版本存在 CVE 漏洞&#xff0c;并且建议升级到 1.3.x 版本。 问题 将两个包直接升级到 1.3.x 版本时&#xff0c;Spring Boot Web 服务启动直接出现…

基于Springboot+Vue+mysql仓库管理系统仓库进销存管理系统

博主介绍&#xff1a; 大家好&#xff0c;本人精通Java、Python、C#、C、C编程语言&#xff0c;同时也熟练掌握微信小程序、Php和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我有丰富的成品Java、Python、C#毕设项目经验&#xff0c;能够为学生提供各类…

nfs服务器详解

nfs&#xff08;网络文件系统&#xff09;---------- 其实就是通过网络将文件共享出去。 通过TCP/IP网络去共享资源的。在NFS的应用中&#xff0c;本地NFS的客户端应用可以透明地读写位于远端NFS服务器上的文件&#xff0c;就像访问本地文件一样。 客户端和服务端需要去读写共…

五分钟搞定什么是系统的平均负载

平均负载定义 平均负载是指单位时间内&#xff0c;系统处于可运行状态和不可中断状态的平均进程数&#xff0c;也就是平均活跃进程数&#xff0c;和CPU使用率没有直接关系。简单理解就是平均负载其实就是平均活跃进程数。 使用uptime命令查看系统平均负载 在linux中&#xf…

【环境】原则

系列文章目录 【引论一】项目管理的意义 【引论二】项目管理的逻辑 【环境】概述 【环境】原则 一、培养项目系统性思维 1.1 系统性思维 1.2 系统性思维的价值 1.3 建模和推演&数字孪生 二、项目的复杂性和如何驾驭复杂性 2.1 复杂性的三个维度 2.2 如何驾驭复杂性 三、…

Qt实现XYModem协议(一)

1 概述 Kermit文件运输协议提供了一条从大型计算机下载文件到微机的途径。它已被用于进行公用数据传输。 其特性如下: Kermit文件运输协议是一个半双工的通信协议。它支持7位ASCII字符。数据以可多达96字节长度的可变长度的分组形式传输。对每个被传送分组需要一个确认。Kerm…

如何利用纯前端技术,实现一个网页版视频编辑器?

纯网页版视频编辑器 一、前言二、功能实现三、所需技术四、部分功能实现4.1 素材预设4.2 多轨道剪辑 一、前言 介绍&#xff1a;本篇文章打算利用纯前端的技术&#xff0c;来实现一个网页版的视频编辑器。为什么突然想做一个这么项目来呢&#xff0c;主要是最近一直在利用手机…

KITTI结果领先地位!Progressive LiDAR Adaptation for Road Detection——PLARD算法

描述 详解一篇基于激光视觉融合的道路检测文章&#xff0c;发表在2019年自动化学报英文版&#xff08;我所主编的业界顶刊&#xff09;中&#xff0c;第三作者是陶大程&#xff0c;业界大佬&#xff0c;可自行进行百度。 为什么选择这篇文章进行分析呢。查看KITTI数据集的分数…
最新文章