python类元编程示例-使用类型注解来检查转换属性值的类框架
用三种方式实现使用类型注解来检查转换属性值的类框架
1 __init_subclass__方式
1.1 代码实现
from collections.abc import Callable # <1>
from typing import Any, NoReturn, get_type_hints
from typing import Dict, Typeclass Field:def __init__(self, name: str, constructor: Callable) -> None: # <2>if not callable(constructor) or constructor is type(None): # <3>raise TypeError(f'{name!r} type hint must be callable')self.name = nameself.constructor = constructordef __set__(self, instance: Any, value: Any) -> None:if value is ...: # <4>value = self.constructor()else:try:value = self.constructor(value) # <5>except (TypeError, ValueError) as e: # <6>type_name = self.constructor.__name__msg = f'{value!r} is not compatible with {self.name}:{type_name}'raise TypeError(msg) from einstance.__dict__[self.name] = value # <7>class Checked:@classmethoddef _fields(cls) -> Dict[str, type]: # <1>return get_type_hints(cls)def __init_subclass__(subclass) -> None: # <2>super().__init_subclass__() # <3>for name, constructor in subclass._fields().items(): # <4>setattr(subclass, name, Field(name, constructor)) # <5>def __init__(self, **kwargs: Any) -> None:for name in self._fields(): # <6>value = kwargs.pop(name, ...) # <7>setattr(self, name, value) # <8>if kwargs: # <9>self.__flag_unknown_attrs(*kwargs) # <10>def __setattr__(self, name: str, value: Any) -> None: # <1>if name in self._fields(): # <2>cls = self.__class__descriptor = getattr(cls, name)descriptor.__set__(self, value) # <3>else: # <4>self.__flag_unknown_attrs(name)def __flag_unknown_attrs(self, *names: str) -> NoReturn: # <5>plural = 's' if len(names) > 1 else ''extra = ', '.join(f'{name!r}' for name in names)cls_name = repr(self.__class__.__name__)raise AttributeError(f'{cls_name} object has no attribute{plural} {extra}')def _asdict(self) -> Dict[str, Any]: # <6>return {name: getattr(self, name)for name, attr in self.__class__.__dict__.items()if isinstance(attr, Field)}def __repr__(self) -> str: # <7>kwargs = ', '.join(f'{key}={value!r}' for key, value in self._asdict().items())return f'{self.__class__.__name__}({kwargs})'
#!/usr/bin/env python3from checkedlib import Checkedclass Movie(Checked):title: stryear: intbox_office: floatif __name__ == '__main__':movie = Movie(title='The Godfather', year=1972, box_office=137)print(movie.title)print(movie)try:# remove the "type: ignore" comment to see Mypy errormovie.year = 'MCMLXXII' # type: ignoreexcept TypeError as e:print(e)try:blockbuster = Movie(title='Avatar', year=2009, box_office='billions')except TypeError as e:print(e)
checked_demo.py执行结果
The Godfather
Movie(title='The Godfather', year=1972, box_office=137.0)
'MCMLXXII' is not compatible with year:int
'billions' is not compatible with box_office:float
A Checked subclass definition requires that keyword arguments are
used to create an instance, and provides a nice __repr__::
>>> class Movie(Checked): # <1>
... title: str # <2>
... year: int
... box_office: float
...
>>> movie = Movie(title='The Godfather', year=1972, box_office=137) # <3>
>>> movie.title
'The Godfather'
>>> movie # <4>
Movie(title='The Godfather', year=1972, box_office=137.0)
The type of arguments is runtime checked during instantiation and when an attribute is set::
>>> blockbuster = Movie(title='Avatar', year=2009, box_office='billions')
Traceback (most recent call last):...
TypeError: 'billions' is not compatible with box_office:float
>>> movie.year = 'MCMLXXII'
Traceback (most recent call last):...
TypeError: 'MCMLXXII' is not compatible with year:int
Attributes not passed as arguments to the constructor are initialized with default values::
>>> Movie(title='Life of Brian')
Movie(title='Life of Brian', year=0, box_office=0.0)
Providing extra arguments to the constructor is not allowed::
>>> blockbuster = Movie(title='Avatar', year=2009, box_office=2000,
... director='James Cameron')
Traceback (most recent call last):...
AttributeError: 'Movie' object has no attribute 'director'
Creating new attributes at runtime is restricted as well::
>>> movie.director = 'Francis Ford Coppola'
Traceback (most recent call last):...
AttributeError: 'Movie' object has no attribute 'director'
The _asdict instance method creates a dict from the attributes
of a Movie object::
>>> movie._asdict()
{'title': 'The Godfather', 'year': 1972, 'box_office': 137.0}
2 代码解释
在这个例子中,__init_subclass__ 和 __init__ 的调用顺序和作用域不同,它们各自处理类和实例级别的逻辑。
调用顺序
__init_subclass__是在子类定义时自动调用的。这发生在任何实例被创建之前,仅在类定义期间触发一次。因此,当定义一个继承了Checked类的新类时,__init_subclass__将被调用来为这个新类设置Field描述符。__init__是在创建类的一个实例时调用的。每次通过类(例如Checked的子类)创建一个新对象时,都会调用__init__方法。
不同的作用
-
__init_subclass__在Checked类中用来自动为每个子类基于类型注解创建并设置Field实例。这些Field实例被设置为类属性,用来管理对应的实例属性。 -
__init__的作用是初始化具体的实例。尽管__init_subclass__已经设置了Field描述符,但是描述符需要在实例化时对具体的属性值进行管理和转换。__init__中的setattr(self, name, value)调用是用来初始化这些实例属性的值,并且触发Field描述符的__set__方法,该方法负责使用提供的构造函数验证和转换这些值。尽管__init_subclass__已经把注解自动创建并分配为Field实例,但这些Field实例实际上是作为类属性存在的。它们不直接持有数据,而是定义了如何通过其__set__和__get__方法处理数据。当你在__init__方法中使用setattr时,实际上是触发了这些Field描述符的__set__方法,它们负责根据构造函数规则来验证和转换赋予实例属性的值。这样,每个实例都可以持有独立的、已经经过验证和转换的数据。 -
__init_subclass__设置了如何管理和验证属性(即通过Field描述符),但并未处理具体的属性值。 -
__init__负责实际设置这些属性的初始值,并触发描述符来处理验证和转换的逻辑。
在调用 __init_subclass__ 之后类的结构会发生一些变化
在这个例子中,使用了 __init_subclass__ 方法和 Checked 类的框架,当 Movie 类被定义继承自 Checked 类时,__init_subclass__ 会自动被调用。这是在类级别发生的,即在任何 Movie 实例被创建之前。
当 Movie 类定义完成并触发 __init_subclass__ 方法时,这里发生的主要变化如下:
-
自动属性创建:
- 对于
Movie类中定义的每个类型注解(title: str,year: int,box_office: float),__init_subclass__会从这些注解中获取信息,并为每个属性创建一个Field实例。
- 对于
-
Field 实例作为类属性:
- 这些
Field实例不直接存储任何数据,而是作为描述符存在。描述符主要负责拦截对这些属性的访问和修改操作。 - 对于每个属性,
Field描述符会设置如何创建(调用相应的类型构造器,如str(),int(),float()),验证和存储其值。
- 这些
__init_subclass__ 方法中的核心操作包括:
- 遍历从
get_type_hints获取到的类型注解。 - 为每个属性(如
title,year,box_office)创建一个Field描述符,并将其作为类属性设置到Movie类上。
这样设置后的 Movie 类的结构将包含以下元素:
title属性关联到一个Field描述符,该描述符使用str作为构造函数。year属性关联到一个Field描述符,该描述符使用int作为构造函数。box_office属性关联到一个Field描述符,该描述符使用float作为构造函数。
类的行为
当创建 Movie 的实例并尝试设置这些属性时:
- 访问或修改这些属性将触发对应的
Field描述符的__set__或__get__方法。 - 如果尝试设置的值类型不正确,
Field的__set__方法将尝试转换值到声明的类型(如将字符串转换为整数)。如果转换失败,将抛出TypeError。
2 类装饰器方式
2.1 代码实现
from collections.abc import Callable # <1>
from typing import Any, NoReturn, get_type_hints
from typing import Dict, Type
class Field:def __init__(self, name: str, constructor: Callable) -> None: # <2>if not callable(constructor) or constructor is type(None):raise TypeError(f'{name!r} type hint must be callable')self.name = nameself.constructor = constructordef __set__(self, instance: Any, value: Any) -> None: # <3>if value is ...: # <4>value = self.constructor()else:try:value = self.constructor(value) # <5>except (TypeError, ValueError) as e:type_name = self.constructor.__name__msg = (f'{value!r} is not compatible with {self.name}:{type_name}')raise TypeError(msg) from einstance.__dict__[self.name] = value # <6># tag::CHECKED_DECORATOR[]
def checked(cls: type) -> type: # <1>for name, constructor in _fields(cls).items(): # <2>setattr(cls, name, Field(name, constructor)) # <3>cls._fields = classmethod(_fields) # type: ignore # <4>instance_methods = ( # <5>__init__,__repr__,__setattr__,_asdict,__flag_unknown_attrs,)for method in instance_methods: # <6>setattr(cls, method.__name__, method)return cls # <7>def _fields(cls: type) -> Dict[str, type]:return get_type_hints(cls)def __init__(self: Any, **kwargs: Any) -> None:for name in self._fields():value = kwargs.pop(name, ...)setattr(self, name, value)if kwargs:self.__flag_unknown_attrs(*kwargs)def __setattr__(self: Any, name: str, value: Any) -> None:if name in self._fields():cls = self.__class__descriptor = getattr(cls, name)descriptor.__set__(self, value)else:self.__flag_unknown_attrs(name)def __flag_unknown_attrs(self: Any, *names: str) -> NoReturn:plural = 's' if len(names) > 1 else ''extra = ', '.join(f'{name!r}' for name in names)cls_name = repr(self.__class__.__name__)raise AttributeError(f'{cls_name} has no attribute{plural} {extra}')def _asdict(self: Any) -> Dict[str, Any]:return {name: getattr(self, name)for name, attr in self.__class__.__dict__.items()if isinstance(attr, Field)}def __repr__(self: Any) -> str:kwargs = ', '.join(f'{key}={value!r}' for key, value in self._asdict().items())return f'{self.__class__.__name__}({kwargs})'
2.2 代码解释
这段代码实现了一个装饰器 checked,它为 Python 类添加强类型检查和自动属性管理的功能。该装饰器使用了 Python 的描述符协议和类型注解来自动验证和初始化类属性。下面逐部分解析代码的功能和工作方式:
Field 类
- 目的:
Field类用作属性描述符,主要负责设置和检索类实例的属性值,并确保值符合指定的类型。 - 构造方法 (
__init__): 接收一个属性名和一个构造函数(类型)。如果构造函数不是可调用的或者是None类型,则抛出TypeError。 - 设置方法 (
__set__): 负责接收和处理对属性的赋值操作。如果值是...(省略符号),则使用构造函数(无参数)创建默认值。如果提供了值,则尝试使用构造函数将值转换为适当的类型。如果转换失败,会抛出TypeError。 - 当从实例访问这个属性(如 instance.title)时,由于缺少 get 方法,Python 的解释器会直接从实例的 dict 字典中查找该属性的值,而不是调用描述符的 get 方法。描述符的 set 方法直接操作了托管实例的 dict 字典,将值存储在由 self.name 指定的键下。这意味着,尽管 Field 对象被设置为类的属性,它并没有拦截获取属性值的操作,而是允许直接从实例的字典中获取这些值。
checked 装饰器
- 功能:通过自动应用类型注解和属性管理,使类成为"检查型"类。
- 实现:
- 自动属性管理:遍历类的类型注解,并为每个注解创建一个
Field描述符,负责管理相应的属性。 - 添加方法:将一系列方法(如
__init__,__repr__,__setattr__,_asdict,__flag_unknown_attrs)添加到被装饰的类中,以支持初始化、属性设置、字典转换和错误管理等功能。
- 自动属性管理:遍历类的类型注解,并为每个注解创建一个
实现的方法
_fields:返回一个字典,包含类的所有类型注解。用于在类中创建Field描述符。__init__:负责初始化新创建的实例。从kwargs中提取每个字段的值,如果未提供,则使用省略符号触发默认构造。__setattr__:当尝试设置属性时,首先检查该属性是否由Field描述符管理。如果是,则使用描述符的__set__方法来设置值,否则抛出属性错误。__flag_unknown_attrs:在尝试设置未知属性或当__init__方法中存在额外的kwargs时被调用,抛出AttributeError。_asdict:返回一个字典,包含由Field描述符管理的所有属性及其值。__repr__:生成类实例的字符串表示,展示所有通过Field管理的属性和它们的值。
使用 checked 装饰器处理子类后类的结构会发生的变化
属性管理
checked 装饰器会遍历子类中通过类型注解定义的属性,并为每个属性创建并分配一个 Field 描述符实例。这些 Field 描述符被设置为类属性,用于管理相应的实例属性。这意味着:
对于每个定义的属性,都会有一个 Field 实例与之关联,负责接收和处理对该属性的所有访问和修改请求。
这些 Field 描述符将确保属性值在设置时被正确地转换和验证,按照定义的类型进行。
方法增强
checked 装饰器还会将几个关键的方法添加到子类中:
init:用于正确地初始化新对象的实例属性,接受关键字参数,每个参数对应一个属性。如果属性未在初始化时提供,将使用其类型的默认构造函数来生成值。
setattr:重写此方法以确保对属性的设置通过 Field 描述符进行,从而利用 Field 的类型检查和转换功能。
repr:提供了一种格式化的方式来描述类实例,显示所有通过 Field 管理的属性和它们的值。
_asdict:允许将对象的属性转换成字典形式,便于查看和使用。
__flag_unknown_attrs:当尝试访问或设置不存在的属性时,此方法将被调用,抛出 AttributeError。
3 元类方式
3.1 代码实现
from collections.abc import Callable
from typing import Any, NoReturn, get_type_hints
from typing import Dict, Typeclass Field:def __init__(self, name: str, constructor: Callable) -> None:if not callable(constructor) or constructor is type(None):raise TypeError(f'{name!r} type hint must be callable')self.name = nameself.storage_name = '_' + name # <1>self.constructor = constructordef __get__(self, instance, owner=None):if instance is None: # <2>return selfreturn getattr(instance, self.storage_name) # <3>def __set__(self, instance: Any, value: Any) -> None:if value is ...:value = self.constructor()else:try:value = self.constructor(value)except (TypeError, ValueError) as e:type_name = self.constructor.__name__msg = f'{value!r} is not compatible with {self.name}:{type_name}'raise TypeError(msg) from esetattr(instance, self.storage_name, value) # <4>class CheckedMeta(type):def __new__(meta_cls, cls_name, bases, cls_dict): # <1>if '__slots__' not in cls_dict: # <2>slots = []type_hints = cls_dict.get('__annotations__', {}) # <3>for name, constructor in type_hints.items(): # <4>field = Field(name, constructor) # <5>cls_dict[name] = field # <6>slots.append(field.storage_name) # <7>cls_dict['__slots__'] = slots # <8>return super().__new__(meta_cls, cls_name, bases, cls_dict) # <9>class Checked(metaclass=CheckedMeta):__slots__ = () # skip CheckedMeta.__new__ processing@classmethoddef _fields(cls) -> Dict[str, type]:return get_type_hints(cls)def __init__(self, **kwargs: Any) -> None:for name in self._fields():value = kwargs.pop(name, ...)setattr(self, name, value)if kwargs:self.__flag_unknown_attrs(*kwargs)def __flag_unknown_attrs(self, *names: str) -> NoReturn:plural = 's' if len(names) > 1 else ''extra = ', '.join(f'{name!r}' for name in names)cls_name = repr(self.__class__.__name__)raise AttributeError(f'{cls_name} object has no attribute{plural} {extra}')def _asdict(self) -> Dict[str, Any]:return {name: getattr(self, name)for name, attr in self.__class__.__dict__.items()if isinstance(attr, Field)}def __repr__(self) -> str:kwargs = ', '.join(f'{key}={value!r}' for key, value in self._asdict().items())return f'{self.__class__.__name__}({kwargs})'
3.2 代码解释
这段代码定义了一个复杂的类装饰和类元编程机制,通过自定义描述符 Field 和元类 CheckedMeta 来自动化处理类属性的类型检查和初始化。这种机制可以用来创建严格类型化的数据结构,确保对象属性在设置时自动进行类型转换和验证。
Field 类
Field 用作属性描述符,负责管理属性的访问和设置。
- 初始化: 接收一个属性名称和一个构造函数。如果构造函数不是可调用的,则抛出异常。此外,它生成一个内部使用的存储属性名 (
storage_name),这通常是私有属性名。 __get__方法: 用于获取属性值。如果instance为None(通常在直接通过类访问属性时发生),返回描述符自身;否则从实例字典中返回相应的值。__set__方法: 设置属性值。如果值为特殊标记...,使用无参数的构造函数创建默认值;否则尝试使用构造函数转换提供的值。如果转换失败,抛出TypeError。
CheckedMeta 元类
CheckedMeta 是一个元类,用于在创建类时自动处理属性的类型注解。
__new__方法: 在创建类对象时被调用。- 检查是否已定义
__slots__,用于优化内存使用。 - 从类定义中获取类型注解,并为每个注解创建一个
Field描述符,将其添加到类字典中。 - 为每个
Field描述符生成的storage_name创建一个对应的槽。 - 最后,使用修改后的类字典调用基类的
__new__方法创建类。
- 检查是否已定义
Checked 类
作为使用 CheckedMeta 元类的示例,这个类提供了以下功能:
- 初始化: 使用关键字参数初始化类的实例。通过
_fields方法获取所有字段,并尝试从kwargs中提取对应的值进行设置。 - 属性设置 (
__setattr__): 拦截所有属性赋值操作,确保通过Field描述符处理。 - 错误处理: 当尝试访问或设置未知属性时,
__flag_unknown_attrs方法会抛出AttributeError。 - 字典转换 (
_asdict): 提供一种将对象属性转换为字典的方法,便于外部访问和操作。 - 字符串表示 (
__repr__): 生成对象的友好字符串表示,展示其所有属性和值。
使用 CheckedMeta 作为元类的子类结构
属性描述符 (Field 实例):
title 关联到一个 Field 实例,此实例用 str 作为构造函数进行类型检查和转换。
year 关联到一个 Field 实例,此实例用 int 作为构造函数进行类型检查和转换。
box_office 关联到一个 Field 实例,此实例用 float 作为构造函数进行类型检查和转换。
槽 (slots):
slots 包含 [‘_title’, ‘_year’, ‘_box_office’],这些是实际存储属性值的内部属性名,避免了使用实例字典。
方法:
类继承自 Checked,因此拥有 init、setattr、_asdict、repr 和 __flag_unknown_attrs 等方法,这些方法提供了初始化、属性设置、错误处理、对象转字典和字符串表示的功能。
类属性与实例属性不能同名的原因
使用 __slots__ 在 Python 类中定义哪些属性名将作为实例属性存储,通常是为了节省内存和提高属性访问速度。当使用 __slots__ 时,Python 不再为每个实例创建一个 __dict__ 字典,而是为这些属性在内存中分配固定位置。
当使用描述符(如 Field 类实例)作为类属性,同时使用 __slots__ 指定实例属性时,需要注意的是:
-
名称冲突:如果一个实例属性与一个类属性(描述符)同名,那么在访问这个属性时,描述符的逻辑将被触发,而不是直接访问实例属性。这是因为类属性(描述符)的访问级别比实例属性更高。
-
描述符协议:描述符协议定义了如何通过描述符对象来控制属性的访问。在你的
Field描述符的实现中,__get__和__set__方法被用来管理访问和设置属性的行为。当你尝试访问一个属性,Python 首先检查该属性是否是一个描述符(即是否有__get__或__set__方法),如果是,则调用这些方法。 -
存储位置:
Field描述符使用storage_name(例如'_title')来在实例中存储数据,而不是直接使用title。这是为了避免直接访问和修改这些属性,从而绕过描述符逻辑。
如何确保描述符的 __get__ 正确执行
为了确保 Field 描述符的 __get__ 方法能够正确执行,你应该这样访问属性:
- 当通过实例访问属性时(例如
movie_instance.title),将调用Field的__get__方法,从实例中的'_title'位置取出值。 - 当直接通过类访问属性时(例如
Movie.title),__get__方法中的instance is None分支将被执行,这通常返回描述符自身或其他与类相关的信息。
4 元类的调用顺序
元类在 Python 中用于创建类,它们本身是类的类。
元类的关键方法
-
__prepare__:- 调用时机: 在类体被执行前调用。
- 功能: 返回一个映射对象,用于在类定义时存储类属性和方法的定义。通常返回的是一个字典,但可以覆盖为其他类型的映射对象。
- 参数: 接受将要创建的类的名称和它的基类。
- 返回值: 用于类体执行的命名空间。
-
__new__:- 调用时机: 在类的实例(即类对象本身)被创建时调用。
- 功能: 负责实际创建类对象。它可以修改类的定义,添加、修改或删除属性,或者根据需要完全改变类的创建过程。
- 参数: 元类、类名、基类元组、类字典(由
__prepare__返回的映射对象),还可以接收额外的关键字参数(如果在类定义中提供)。 - 返回值: 返回一个新的类对象。
-
__init__:- 调用时机: 在类对象创建后被调用,用于初始化新创建的类对象。
- 功能: 初始化新创建的类对象。与
__new__不同,__init__不返回任何值,它仅用于初始化操作。 - 参数: 类对象、类名、基类元组、字典。
-
__init_subclass__:- 调用时机: 这是一个类方法,当类被继承时自动调用。
- 功能: 用于在创建子类时执行初始化或其他配置工作。
- 参数: 子类和任何在子类定义时传递的关键字参数。
- 返回值: 通常无返回值,用于设置子类或进行检查。
调用顺序示例
假设我们有一个元类 Meta 和使用这个元类的类 MyClass:
class Meta(type):def __prepare__(name, bases, **kwargs):print("Meta.__prepare__ called")return super().__prepare__(name, bases, **kwargs)def __new__(cls, name, bases, namespace, **kwargs):print("Meta.__new__ called")return super().__new__(cls, name, bases, namespace, **kwargs)def __init__(cls, name, bases, namespace, **kwargs):print("Meta.__init__ called")super().__init__(name, bases, namespace, **kwargs)def __init_subclass__(cls, **kwargs):print("Meta.__init_subclass__ called")super().__init_subclass__(**kwargs)class MyClass(metaclass=Meta):passclass MySubClass(MyClass):pass
调用顺序为:
Meta.__prepare__被调用来准备MyClass的命名空间。- 类体
MyClass执行。 Meta.__new__被调用来创建MyClass类对象。Meta.__init__被调用来初始化MyClass类对象。Meta.__init_subclass__被调用(如果在MyClass中定义)。- 当
MySubClass被定义时,上述步骤(1-4)重复执行,此外,MyClass.__init_subclass__也会被调用来处理子类的创建。
参考《流程的python》第24章
相关文章:
python类元编程示例-使用类型注解来检查转换属性值的类框架
用三种方式实现使用类型注解来检查转换属性值的类框架 1 __init_subclass__方式 1.1 代码实现 from collections.abc import Callable # <1> from typing import Any, NoReturn, get_type_hints from typing import Dict, Typeclass Field:def __init__(self, name: …...
Python3 笔记:字符串的 zfill() 和 rjust()
1、zfill() 方法返回指定长度的字符串,原字符串右对齐,前面填充0。 语法:str.zfill(width) width :指定字符串的长度。原字符串右对齐,前面填充0。 str1 2546 str2 2 print(str1.zfill(10)) # 运行结果࿱…...
SpringBoot项目启动提示端口号占用
Windows环境下,SpringBoot项目启动时报端口号占用: *************************** APPLICATION FAILED TO START ***************************Description:Web server failed to start. Port 8080 was already in use.Action:Identify and stop the proc…...
音视频开发23 FFmpeg 音频重采样
代码实现的功能 目的是 将: 一个采样率为 44100,采样通道为 2,格式为 AV_SAMPLE_FMT_DBL 的 in.pcm 数据 转换成 一个采样率为 48000,采样通道为 1,格式为 AV_SAMPLE_FMT_S16 的 out.pcm 数据 1.重采样 1.1 为什么要重…...
windows系统下安装fnm
由于最近做项目要切换多个node版本,查询了一下常用的有nvm和fnm这两种,对比了一下选择了fnm。 下载fnm 有两种方式,目前最新版本是1.37.0: 1.windows下打开powershell,执行以下命令下载fnm winget install Schniz.f…...
【Linux网络】传输层协议 - UDP
文章目录 一、传输层(运输层)运输层的特点复用和分用再谈端口号端口号范围划分认识知名端口号(Well-Know Port Number)两个问题① 一个进程是否可以绑定多个端口号?② 一个端口号是否可以被多个进程绑定? n…...
debugger(四):源代码
〇、前言 终于来到令人激动的源代码 level 了,这里将会有一些很有意思的算法,来实现源代码级别的调试,这将会非常有趣。 一、使用 libelfin 库 我们不可能直接去读取整个 .debug info 段来进行设置,这是没有必要的,…...
基于运动控制卡的圆柱坐标机械臂设计
1 方案简介 介绍一种基于运动控制卡制作一款scara圆柱坐标的机械臂设计方案,该方案控制器用运动控制卡制作一台三轴机械臂,用于自动抓取和放料操作。 2 组成部分 该机械臂的组成部分有研华运动控制卡,触摸屏,三轴圆柱坐标的平面运…...
MongoDBTemplate-基本文档查询
文章目录 流程概述步骤1:创建一个MongoDB的连接步骤2:创建一个查询对象Query步骤3:设置需要查询的字段步骤4:使用查询对象执行查询操作 流程概述 步骤描述步骤1创建一个MongoDB的连接步骤2创建一个查询对象Query步骤3设置需要查询…...
23种设计模式——创建型模式
设计模式 文章目录 设计模式创建型模式单例模式 [1-小明的购物车](https://kamacoder.com/problempage.php?pid1074)工厂模式 [2-积木工厂](https://kamacoder.com/problempage.php?pid1076)抽象⼯⼚模式 [3-家具工厂](https://kamacoder.com/problempage.php?pid1077)建造者…...
idm究竟有哪些优势
IDM(Internet Download Manager)是一款广受好评的下载管理工具,其主要优势包括: 高速下载:IDM支持最大32线程的下载,可以显著提升下载速度1。文件分类下载:IDM可以根据文件后缀进行分类&#x…...
如何学习Golang语言!
第一部分:Go语言概述 起源与设计哲学:Go语言由Robert Griesemer、Rob Pike和Ken Thompson三位Google工程师设计,旨在解决现代编程中的一些常见问题,如编译速度、运行效率和并发编程。主要特点:Go语言的语法简单、编译…...
Redis系列之淘汰策略介绍
Redis系列之淘汰策略介绍 文章目录 为什么需要Redis淘汰策略?Redis淘汰策略分类Redis数据淘汰流程源码验证淘汰流程Redis中的LRU算法Redis中的LFU算法 为什么需要Redis淘汰策略? 由于Redis内存是有大小的,当内存快满的时候,又没有…...
sql 调优
sql 调优 SQL调优是一个复杂的过程,涉及多个方面,包括查询优化、索引优化、表结构优化等。以下是一些基本的SQL调优策略: 使用索引:确保查询中涉及的列都有适当的索引。 查询优化:避免使用SELECT *,只选取…...
【UML用户指南】-13-对高级结构建模-包
目录 1、名称 2、元素 3、可见性 4、引入与引出 用包把建模元素安排成可作为一个组来处理的较大组块。可以控制这些元素的可见性,使一些元素在包外是可见的,而另一些元素要隐藏在包内。也可以用包表示系统体系结构的不同视图。 狗窝并不复杂&#x…...
前端面试题日常练-day63 【面试题】
题目 希望这些选择题能够帮助您进行前端面试的准备,答案在文末 1. TypeScript中,以下哪个关键字用于声明一个类的构造函数? a) constructor b) init c) create d) initialize 2. 在TypeScript中,以下哪个符号用于声明可选的函…...
GAN的入门理解
这一篇主要是关于生成对抗网络的模型笔记,有一些简单的证明和原理,是根据李宏毅老师的课程整理的,下面有链接。本篇文章主要就是梳理基础的概念和训练过程,如果有什么问题的话也可以指出的。 李宏毅老师的课程链接 1.概述 GAN是…...
43【PS 作图】颜色速途
1 通过PS让画面细节模糊,避免被过多的颜色干扰 2 分析画面的颜色 3 作图 参考网站: 色感不好要怎么提升呢?分享一下我是怎么练习色感的!_哔哩哔哩_bilibili https://www.bilibili.com/video/BV1h1421Z76p/?spm_id_from333.1007.…...
定个小目标之刷LeetCode热题(13)
今天来看看这道题,介绍两种解法 第一种动态规划,代码如下 class Solution {public int maxSubArray(int[] nums) {int pre 0, maxAns nums[0];for (int x : nums) {// 计算当前最大前缀和pre Math.max(pre x, x);// 更新最大前缀和maxAns Math.ma…...
【AI大模型】Prompt Engineering
目录 什么是提示工程(Prompt Engineering) Prompt 调优 Prompt 的典型构成 「定义角色」为什么有效? 防止 Prompt 攻击 攻击方式 1:著名的「奶奶漏洞」 攻击方式 2:Prompt 注入 防范措施 1:Prompt 注…...
Ubuntu系统下交叉编译openssl
一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机:Ubuntu 20.04.6 LTSHost:ARM32位交叉编译器:arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...
汽车生产虚拟实训中的技能提升与生产优化
在制造业蓬勃发展的大背景下,虚拟教学实训宛如一颗璀璨的新星,正发挥着不可或缺且日益凸显的关键作用,源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例,汽车生产线上各类…...
DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI
前一阵子在百度 AI 开发者大会上,看到基于小智 AI DIY 玩具的演示,感觉有点意思,想着自己也来试试。 如果只是想烧录现成的固件,乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外,还提供了基于网页版的 ESP LA…...
Redis数据倾斜问题解决
Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中,部分节点存储的数据量或访问量远高于其他节点,导致这些节点负载过高,影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...
【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...
NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合
在汽车智能化的汹涌浪潮中,车辆不再仅仅是传统的交通工具,而是逐步演变为高度智能的移动终端。这一转变的核心支撑,来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒(T-Box)方案:NXP S32K146 与…...
return this;返回的是谁
一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请,不同级别的经理有不同的审批权限: // 抽象处理者:审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...
Linux中《基础IO》详细介绍
目录 理解"文件"狭义理解广义理解文件操作的归类认知系统角度文件类别 回顾C文件接口打开文件写文件读文件稍作修改,实现简单cat命令 输出信息到显示器,你有哪些方法stdin & stdout & stderr打开文件的方式 系统⽂件I/O⼀种传递标志位…...
QT开发技术【ffmpeg + QAudioOutput】音乐播放器
一、 介绍 使用ffmpeg 4.2.2 在数字化浪潮席卷全球的当下,音视频内容犹如璀璨繁星,点亮了人们的生活与工作。从短视频平台上令人捧腹的搞笑视频,到在线课堂中知识渊博的专家授课,再到影视平台上扣人心弦的高清大片,音…...
DeepSeek越强,Kimi越慌?
被DeepSeek吊打的Kimi,还有多少人在用? 去年,月之暗面创始人杨植麟别提有多风光了。90后清华学霸,国产大模型六小虎之一,手握十几亿美金的融资。旗下的AI助手Kimi烧钱如流水,单月光是投流就花费2个亿。 疯…...
