​functools --- 高阶函数和可调用对象上的操作​

源代码: Lib/functools.py


functools 模块应用于高阶函数,即参数或(和)返回值为其他函数的函数。 通常来说,此模块的功能适用于所有可调用对象。

functools 模块定义了以下函数:

@functools.cache(user_function)

简单轻量级未绑定函数缓存。 有时称为 "memoize"。

返回值与 lru_cache(maxsize=None) 相同,创建一个查找函数参数的字典的简单包装器。 因为它不需要移出旧值,所以比带有大小限制的 lru_cache() 更小更快。

例如:

@cache
def factorial(n):return n * factorial(n-1) if n else 1>>> factorial(10)      # no previously cached result, makes 11 recursive calls
3628800
>>> factorial(5)       # just looks up cached value result
120
>>> factorial(12)      # makes two new recursive calls, the other 10 are cached
479001600

该缓存是线程安全的因此被包装的函数可在多线程中使用。 这意味着下层的数据结构将在并发更新期间保持一致性。

如果另一个线程在初始调用完成并被缓存之前执行了额外的调用则被包装的函数可能会被多次调用。

3.9 新版功能.

@functools.cached_property(func)

将一个类方法转换为特征属性,一次性计算该特征属性的值,然后将其缓存为实例生命周期内的普通属性。 类似于 property() 但增加了缓存功能。 对于在其他情况下实际不可变的高计算资源消耗的实例特征属性来说该函数非常有用。

示例:

class DataSet:def __init__(self, sequence_of_numbers):self._data = tuple(sequence_of_numbers)@cached_propertydef stdev(self):return statistics.stdev(self._data)

cached_property() 的设定与 property() 有所不同。 常规的 property 会阻止属性写入,除非定义了 setter。 与之相反,cached_property 则允许写入。

cached_property 装饰器仅在执行查找且不存在同名属性时才会运行。 当运行时,cached_property 会写入同名的属性。 后续的属性读取和写入操作会优先于 cached_property 方法,其行为就像普通的属性一样。

缓存的值可通过删除该属性来清空。 这允许 cached_property 方法再次运行。

cached_property 不能防止在多线程使用中可能出现的竞争条件。 getter 函数可以在同一实例上多次运行,最后一次运行将设置缓存值。 如果缓存的特征属性是幂等的或者对于在同一实例上多次运行是无害的,那就没有问题。 如果需要进行同步,请在被装饰的 getter 函数内部或在缓存的特征属性访问外部实现必要的锁定操作。

注意,这个装饰器会影响 PEP 412 键共享字典的操作。 这意味着相应的字典实例可能占用比通常时更多的空间。

而且,这个装饰器要求每个实例上的 __dict__ 是可变的映射。 这意味着它将不适用于某些类型,例如元类(因为类型实例上的 __dict__ 属性是类命名空间的只读代理),以及那些指定了 __slots__ 但未包括 __dict__ 作为所定义的空位之一的类(因为这样的类根本没有提供 __dict__ 属性)。

如果可变的映射不可用或者如果想要节省空间的键共享,可以通过在 lru_cache() 上堆叠 property() 来实现类似 cached_property() 的效果。 请参阅 我该如何缓存方法调用? 了解这与 cached_property() 之间区别的详情。

3.8 新版功能.

在 3.12 版更改: 在 Python 3.12 之前,cached_property 包括了一个未写入文档的锁用来确保在多线程使用中 getter 函数对于每个实例保证只运行一次。 但是,这个锁是针对特征属性的,不是针对实例的,这可能导致不可接受的高强度锁争用。 在 Python 3.12+ 中这个锁已被移除。

functools.cmp_to_key(func)

将(旧式的)比较函数转换为新式的 key function . 在类似于 sorted() , min() , max() , heapq.nlargest() , heapq.nsmallest() , itertools.groupby() 等函数的 key 参数中使用。此函数主要用作将 Python 2 程序转换至新版的转换工具,以保持对比较函数的兼容。

比较函数是任何接受两个参数,对它们进行比较,并在结果为小于时返回一个负数,相等时返回零,大于时返回一个正数的可调用对象。 键函数是接受一个参数并返回另一个用作排序键的值的可调用对象。

示例:

sorted(iterable, key=cmp_to_key(locale.strcoll))  # locale-aware sort order

有关排序示例和简要排序教程,请参阅 排序指南 。

3.2 新版功能.

@functools.lru_cache(user_function)

@functools.lru_cache(maxsize=128typed=False)

一个为函数提供缓存功能的装饰器,缓存 maxsize 组传入参数,在下次以相同参数调用时直接返回上一次的结果。用以节约高开销或I/O函数的调用时间。

该缓存是线程安全的因此被包装的函数可在多线程中使用。 这意味着下层的数据结构将在并发更新期间保持一致性。

如果另一个线程在初始调用完成并被缓存之前执行了额外的调用则被包装的函数可能会被多次调用。

由于使用字典来缓存结果,因此传给该函数的位置和关键字参数必须为 hashable。

不同的参数模式可能会被视为具有单独缓存项的不同调用。 例如,f(a=1, b=2) 和 f(b=2, a=1) 因其关键字参数顺序不同而可能会具有两个单独的缓存项。

如果指定了 user_function,它必须是一个可调用对象。 这允许 lru_cache 装饰器被直接应用于一个用户自定义函数,让 maxsize 保持其默认值 128:

@lru_cache
def count_vowels(sentence):return sum(sentence.count(vowel) for vowel in 'AEIOUaeiou')

如果 maxsize 设为 None,LRU 特性将被禁用且缓存可无限增长。

如果 typed 被设置为 true ,不同类型的函数参数将被分别缓存。 如果 typed 为 false ,实现通常会将它们视为等价的调用,只缓存一个结果。(有些类型,如 str 和 int ,即使 typed 为 false ,也可能被分开缓存)。

注意,类型的特殊性只适用于函数的直接参数而不是它们的内容。 标量参数 Decimal(42) 和 Fraction(42) 被视为具有不同结果的不同调用。相比之下,元组参数 ('answer', Decimal(42)) 和 ('answer', Fraction(42)) 被视为等同的。

被包装的函数配有一个 cache_parameters() 函数,该函数返回一个新的 dict 用来显示 maxsize 和 typed 的值。 这只是出于显示信息的目的。 改变值没有任何效果。

为了帮助衡量缓存的有效性以及调整 maxsize 形参,被包装的函数会带有一个 cache_info() 函数,它返回一个 named tuple 以显示 hitsmissesmaxsize 和 currsize

该装饰器也提供了一个用于清理/使缓存失效的函数 cache_clear() 。

原始的未经装饰的函数可以通过 __wrapped__ 属性访问。它可以用于检查、绕过缓存,或使用不同的缓存再次装饰原始函数。

缓存会保持对参数的引用并返回值,直到它们结束生命期退出缓存或者直到缓存被清空。

如果一个方法被缓存,则 self 实例参数会被包括在缓存中。 请参阅 我该如何缓存方法调用?

LRU(最久未使用算法)缓存 在最近的调用是即将到来的调用的最佳预测值时性能最好(例如,新闻服务器上最热门文章倾向于每天更改)。 缓存的大小限制可确保缓存不会在长期运行进程如网站服务器上无限制地增长。

一般来说,LRU 缓存只应在你需要重复使用先前计算的值时使用。 因此,缓存有附带影响的函数、每次调用都需要创建不同的可变对象的函数(如生成器和异步函数)或不纯的函数如 time() 或 random() 等是没有意义的。

静态 Web 内容的 LRU 缓存示例:

@lru_cache(maxsize=32)
def get_pep(num):'Retrieve text of a Python Enhancement Proposal'resource = f'https://peps.python.org/pep-{num:04d}'try:with urllib.request.urlopen(resource) as s:return s.read()except urllib.error.HTTPError:return 'Not Found'>>> for n in 8, 290, 308, 320, 8, 218, 320, 279, 289, 320, 9991:
...     pep = get_pep(n)
...     print(n, len(pep))>>> get_pep.cache_info()
CacheInfo(hits=3, misses=8, maxsize=32, currsize=8)

以下是使用缓存通过 动态规划 计算 斐波那契数列 的例子。

@lru_cache(maxsize=None)
def fib(n):if n < 2:return nreturn fib(n-1) + fib(n-2)>>> [fib(n) for n in range(16)]
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610]>>> fib.cache_info()
CacheInfo(hits=28, misses=16, maxsize=None, currsize=16)

3.2 新版功能.

在 3.3 版更改: 添加 typed 选项。

在 3.8 版更改: 添加了 user_function 选项。

3.9 新版功能: 新增函数 cache_parameters()

@functools.total_ordering

给定一个声明一个或多个全比较排序方法的类,这个类装饰器实现剩余的方法。这减轻了指定所有可能的全比较操作的工作。

此类必须包含以下方法之一:__lt__() 、__le__()__gt__() 或 __ge__()。另外,此类必须支持 __eq__() 方法。

例如:

@total_ordering
class Student:def _is_valid_operand(self, other):return (hasattr(other, "lastname") andhasattr(other, "firstname"))def __eq__(self, other):if not self._is_valid_operand(other):return NotImplementedreturn ((self.lastname.lower(), self.firstname.lower()) ==(other.lastname.lower(), other.firstname.lower()))def __lt__(self, other):if not self._is_valid_operand(other):return NotImplementedreturn ((self.lastname.lower(), self.firstname.lower()) <(other.lastname.lower(), other.firstname.lower()))

备注

虽然此装饰器使得创建具有良好行为的完全有序类型变得非常容易,但它 确实 是以执行速度更缓慢和派生比较方法的堆栈回溯更复杂为代价的。 如果性能基准测试表明这是特定应用的瓶颈所在,则改为实现全部六个富比较方法应该会轻松提升速度。

备注

这个装饰器不会尝试重载类 或其上级类 中已经被声明的方法。 这意味着如果某个上级类定义了比较运算符,则 total_ordering 将不会再次实现它,即使原方法是抽象方法。

3.2 新版功能.

在 3.4 版更改: 现在已支持从未识别类型的下层比较函数返回 NotImplemented 异常。

functools.partial(func/*args**keywords)

返回一个新的 部分对象,当被调用时其行为类似于 func 附带位置参数 args 和关键字参数 keywords 被调用。 如果为调用提供了更多的参数,它们会被附加到 args。 如果提供了额外的关键字参数,它们会扩展并重载 keywords。 大致等价于:

def partial(func, /, *args, **keywords):def newfunc(*fargs, **fkeywords):newkeywords = {**keywords, **fkeywords}return func(*args, *fargs, **newkeywords)newfunc.func = funcnewfunc.args = argsnewfunc.keywords = keywordsreturn newfunc

partial() 会被“冻结了”一部分函数参数和/或关键字的部分函数应用所使用,从而得到一个具有简化签名的新对象。 例如,partial() 可用来创建一个行为类似于 int() 函数的可调用对象,其中 base 参数默认为二:

>>>

>>> from functools import partial
>>> basetwo = partial(int, base=2)
>>> basetwo.__doc__ = 'Convert base 2 string to an int.'
>>> basetwo('10010')
18

class functools.partialmethod(func/*args**keywords)

返回一个新的 partialmethod 描述器,其行为类似 partial 但它被设计用作方法定义而非直接用作可调用对象。

func 必须是一个 descriptor 或可调用对象(同属两者的对象例如普通函数会被当作描述器来处理)。

当 func 是一个描述器(例如普通 Python 函数, classmethod(), staticmethod(), abstractmethod() 或其他 partialmethod 的实例)时, 对 __get__ 的调用会被委托给底层的描述器,并会返回一个适当的 部分对象 作为结果。

当 func 是一个非描述器类可调用对象时,则会动态创建一个适当的绑定方法。 当用作方法时其行为类似普通 Python 函数:将会插入 self 参数作为第一个位置参数,其位置甚至会处于提供给 partialmethod 构造器的 args 和 keywords 之前。

示例:

>>>

>>> class Cell:
...     def __init__(self):
...         self._alive = False
...     @property
...     def alive(self):
...         return self._alive
...     def set_state(self, state):
...         self._alive = bool(state)
...     set_alive = partialmethod(set_state, True)
...     set_dead = partialmethod(set_state, False)
...
>>> c = Cell()
>>> c.alive
False
>>> c.set_alive()
>>> c.alive
True

3.4 新版功能.

functools.reduce(functioniterable[, initializer])

将两个参数的 function 从左至右积累地应用到 iterable 的条目,以便将该可迭代对象缩减为单一的值。 例如,reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) 是计算 ((((1+2)+3)+4)+5) 的值。 左边的参数 x 是积累值而右边的参数 y 则是来自 iterable 的更新值。 如果存在可选项 initializer,它会被放在参与计算的可迭代对象的条目之前,并在可迭代对象为空时作为默认值。 如果没有给出 initializer 并且 iterable 仅包含一个条目,则将返回第一项。

大致相当于:

def reduce(function, iterable, initializer=None):it = iter(iterable)if initializer is None:value = next(it)else:value = initializerfor element in it:value = function(value, element)return value

请参阅 itertools.accumulate() 了解有关可产生所有中间值的迭代器。

@functools.singledispatch

将一个函数转换为 单分派 generic function。

要定义一个泛型函数,用装饰器 @singledispatch 来装饰它。当使用 @singledispatch 定义一个函数时,请注意调度发生在第一个参数的类型上:

>>>

>>> from functools import singledispatch
>>> @singledispatch
... def fun(arg, verbose=False):
...     if verbose:
...         print("Let me just say,", end=" ")
...     print(arg)

要将重载的实现添加到函数中,请使用泛型函数的 register() 属性,它可以被用作装饰器。 对于带有类型标注的函数,该装饰器将自动推断第一个参数的类型:

>>>

>>> @fun.register
... def _(arg: int, verbose=False):
...     if verbose:
...         print("Strength in numbers, eh?", end=" ")
...     print(arg)
...
>>> @fun.register
... def _(arg: list, verbose=False):
...     if verbose:
...         print("Enumerate this:")
...     for i, elem in enumerate(arg):
...         print(i, elem)

还可以使用 types.UnionType 和 typing.Union:

>>>

>>> @fun.register
... def _(arg: int | float, verbose=False):
...     if verbose:
...         print("Strength in numbers, eh?", end=" ")
...     print(arg)
...
>>> from typing import Union
>>> @fun.register
... def _(arg: Union[list, set], verbose=False):
...     if verbose:
...         print("Enumerate this:")
...     for i, elem in enumerate(arg):
...         print(i, elem)
...

对于不使用类型标注的代码,可以将适当的类型参数显式地传给装饰器本身:

>>>

>>> @fun.register(complex)
... def _(arg, verbose=False):
...     if verbose:
...         print("Better than complicated.", end=" ")
...     print(arg.real, arg.imag)
...

要启用注册 lambda 和现有的函数,也可以使用 register() 属性的函数形式:

>>>

>>> def nothing(arg, verbose=False):
...     print("Nothing.")
...
>>> fun.register(type(None), nothing)

register() 属性会返回未被装饰的函数。 这将启用装饰器栈、封存,并为每个变量单独创建单元测试:

>>>

>>> @fun.register(float)
... @fun.register(Decimal)
... def fun_num(arg, verbose=False):
...     if verbose:
...         print("Half of your number:", end=" ")
...     print(arg / 2)
...
>>> fun_num is fun
False

在调用时,泛型函数会根据第一个参数的类型进行分派:

>>>

>>> fun("Hello, world.")
Hello, world.
>>> fun("test.", verbose=True)
Let me just say, test.
>>> fun(42, verbose=True)
Strength in numbers, eh? 42
>>> fun(['spam', 'spam', 'eggs', 'spam'], verbose=True)
Enumerate this:
0 spam
1 spam
2 eggs
3 spam
>>> fun(None)
Nothing.
>>> fun(1.23)
0.615

在没有针对特定类型的已注册实现的情况下,会使用其方法解析顺序来查找更通用的实现。 使用 @singledispatch 装饰的原始函数将为基本的 object 类型进行注册,这意味着它将在找不到更好的实现时被使用。

如果一个实现被注册到 abstract base class,则基类的虚拟子类将被发送到该实现:

>>>

>>> from collections.abc import Mapping
>>> @fun.register
... def _(arg: Mapping, verbose=False):
...     if verbose:
...         print("Keys & Values")
...     for key, value in arg.items():
...         print(key, "=>", value)
...
>>> fun({"a": "b"})
a => b

要检查泛型函数将为给定的类型选择哪个实现,请使用 dispatch() 属性:

>>>

>>> fun.dispatch(float)
<function fun_num at 0x1035a2840>
>>> fun.dispatch(dict)    # note: default implementation
<function fun at 0x103fe0000>

要访问所有已注册实现,请使用只读的 registry 属性:

>>>

>>> fun.registry.keys()
dict_keys([<class 'NoneType'>, <class 'int'>, <class 'object'>,<class 'decimal.Decimal'>, <class 'list'>,<class 'float'>])
>>> fun.registry[float]
<function fun_num at 0x1035a2840>
>>> fun.registry[object]
<function fun at 0x103fe0000>

3.4 新版功能.

在 3.7 版更改: register() 属性现在支持使用类型标注。

在 3.11 版更改: register() 属性现在支持将 types.UnionType 和 typing.Union 作为类型标注。

class functools.singledispatchmethod(func)

将一个方法转换为 单分派 generic function。

要定义一个泛型方法,请用 @singledispatchmethod 装饰器来装饰它。 当使用 @singledispatchmethod 定义一个函数时,请注意发送操作将针对第一个非 self 或非 cls 参数的类型上:

class Negator:@singledispatchmethoddef neg(self, arg):raise NotImplementedError("Cannot negate a")@neg.registerdef _(self, arg: int):return -arg@neg.registerdef _(self, arg: bool):return not arg

@singledispatchmethod 支持与其他装饰器如 @classmethod 相嵌套。 请注意为了允许 dispatcher.registersingledispatchmethod 必须是 最外层的 装饰器。 下面是一个 Negator 类包含绑定到类的 neg 方法,而不是一个类实例:

class Negator:@singledispatchmethod@classmethoddef neg(cls, arg):raise NotImplementedError("Cannot negate a")@neg.register@classmethoddef _(cls, arg: int):return -arg@neg.register@classmethoddef _(cls, arg: bool):return not arg

同样的模式也可被用于其他类似的装饰器: @staticmethod, @abstractmethod 等等。

3.8 新版功能.

functools.update_wrapper(wrapperwrappedassigned=WRAPPER_ASSIGNMENTSupdated=WRAPPER_UPDATES)

更新一个 wrapper 函数以使其类似于 wrapped 函数。 可选参数为指明原函数的哪些属性要直接被赋值给 wrapper 函数的匹配属性的元组,并且这些 wrapper 函数的属性将使用原函数的对应属性来更新。 这些参数的默认值是模块级常量 WRAPPER_ASSIGNMENTS (它将被赋值给 wrapper 函数的 __module____name____qualname____annotations__ 和 __doc__ 即文档字符串) 以及 WRAPPER_UPDATES (它将更新 wrapper 函数的 __dict__ 即实例字典)。

为了允许出于内省和其他目的访问原始函数(例如绕过 lru_cache() 之类的缓存装饰器),此函数会自动为 wrapper 添加一个指向被包装函数的 __wrapped__ 属性。

此函数的主要目的是在 decorator 函数中用来包装被装饰的函数并返回包装器。 如果包装器函数未被更新,则被返回函数的元数据将反映包装器定义而不是原始函数定义,这通常没有什么用处。

update_wrapper() 可以与函数之外的可调用对象一同使用。 在 assigned 或 updated 中命名的任何属性如果不存在于被包装对象则会被忽略(即该函数将不会尝试在包装器函数上设置它们)。 如果包装器函数自身缺少在 updated 中命名的任何属性则仍将引发 AttributeError。

3.2 新版功能: 自动添加 __wrapped__ 属性。

3.2 新版功能: 默认拷贝 __annotations__ 属性。

在 3.2 版更改: 不存在的属性将不再触发 AttributeError。

在 3.4 版更改: __wrapped__ 属性现在总是指向被包装的函数,即使该函数定义了 __wrapped__ 属性。 (参见 bpo-17482)

@functools.wraps(wrappedassigned=WRAPPER_ASSIGNMENTSupdated=WRAPPER_UPDATES)

这是一个便捷函数,用于在定义包装器函数时发起调用 update_wrapper() 作为函数装饰器。 它等价于 partial(update_wrapper, wrapped=wrapped, assigned=assigned, updated=updated)。 例如:

>>>

>>> from functools import wraps
>>> def my_decorator(f):
...     @wraps(f)
...     def wrapper(*args, **kwds):
...         print('Calling decorated function')
...         return f(*args, **kwds)
...     return wrapper
...
>>> @my_decorator
... def example():
...     """Docstring"""
...     print('Called example function')
...
>>> example()
Calling decorated function
Called example function
>>> example.__name__
'example'
>>> example.__doc__
'Docstring'

如果不使用这个装饰器工厂函数,则 example 函数的名称将变为 'wrapper',并且 example() 原本的文档字符串将会丢失。

partial 对象

partial 对象是由 partial() 创建的可调用对象。 它们具有三个只读属性:

partial.func

一个可调用对象或函数。 对 partial 对象的调用将被转发给 func 并附带新的参数和关键字。

partial.args

最左边的位置参数将放置在提供给 partial 对象调用的位置参数之前。

partial.keywords

当调用 partial 对象时将要提供的关键字参数。

partial 对象与 function 对象的类似之处在于它们都是可调用、可弱引用的对象并可拥有属性。 但两者也存在一些重要的区别。 例如前者不会自动创建 __name__ 和 __doc__ 属性。 而且,在类中定义的 partial 对象的行为类似于静态方法,并且不会在实例属性查找期间转换为绑定方法。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Vellum —— Fluid

目录 Vellum fluids setups Fluid tips and troubleshooting Fluid phases Vellum fluids and soft bodies Vellum fluid vs FLIP fluid Vellum fluids setups Vellum fluid solver是基于粒子流体的解算框架&#xff0c;被完全集成到了Vellum动力学系统&#xff08;可与gr…

王道数据结构课后代码题 p149 第3—— 7(c语言代码实现)

目录 3.编写后序遍历二叉树的非递归算法 4.试给出二叉树的自下而上、自右到左的层次遍历算法 &#xff08;有图解代码详解&#xff09;c语言代码实现 5.假设二叉树采用二叉链表存储结构&#xff0c;设计一个非递归算法求二叉树的高度。 ​编辑 6.设一棵二叉树中各结点的值互不…

普冉(PUYA)单片机开发笔记(7): ADC-轮询式多路采样

概述 应用中经常会有使用单片机进行模数转换的需求。PY32F003 具有 1 个 12 位的模拟数字转换器&#xff08;ADC&#xff09;&#xff0c;今天我们一起来使用一下这个 ADC。 数据手册中对 ADC 简介如下。 SAR ADC&#xff1a;逐次逼近式 ADC&#xff0c;原理参见“参考链接&a…

class070 子数组最大累加和问题与扩展-上【算法】

class070 子数组最大累加和问题与扩展-上【算法】 code1 53. 最大子数组和 // 累加和最大子数组和 // 给你一个整数数组 nums // 请你找出一个具有最大累加和的非空子数组 // 返回其最大累加和 // 测试链接 : https://leetcode.cn/problems/maximum-subarray/ dp[i]&#xff…

【Docker】Docker Compose,yml 配置指令参考的详细讲解

作者简介&#xff1a; 辭七七&#xff0c;目前大二&#xff0c;正在学习C/C&#xff0c;Java&#xff0c;Python等 作者主页&#xff1a; 七七的个人主页 文章收录专栏&#xff1a; 七七的闲谈 欢迎大家点赞 &#x1f44d; 收藏 ⭐ 加关注哦&#xff01;&#x1f496;&#x1f…

基于c++版数据结构基于数组栈改-Python思维总结

##栈部分-&#xff08;叠猫猫&#xff09; ##抽象数据类型栈的定义&#xff1a;是一种遵循先入后出的逻辑的线性数据结构。 换种方式去理解这种数据结构如果我们在一摞盘子中取到下面的盘子&#xff0c;我们首先要把最上面的盘子依次拿走&#xff0c;才可以继续拿下面的盘子&…

【Java期末复习资料】(2)常见例题 //持续更新

本文章主要是常见例题&#xff0c;解析不会太详细&#xff0c;有问题、不会的可以给我发消息哦&#xff0c;后续会出模拟卷 常见例题&#xff1a; 1.下列跟Java技术平台有关的是&#xff08;ABD&#xff09; A.JVM B.JDK C.JPN D.JRE 2.面向对象的特征包括&#xff08;ACD&…

wxPython的控件tree

wxPython树控件介绍 树&#xff08;tree&#xff09;是一种通过层次结构展示信息的控件&#xff0c;如下图所示是树控件示例&#xff0c;左窗口中是树控件&#xff0c;在wxPython中树控件类是wx.TreeCtrl。 wx.TreeCtrl常用的方法有 AddRoot(text, image-1, selImage-1, data…

在Deepin中安装x11vnc工具并结合内网穿透软件实现远程访问桌面

文章目录 1. 安装x11vnc2. 本地远程连接测试3. Deepin安装Cpolar4. 配置公网远程地址5. 公网远程连接Deepin桌面6. 固定连接公网地址7. 固定公网地址连接测试 x11vnc是一种在Linux系统中实现远程桌面控制的工具&#xff0c;它的原理是通过X Window系统的协议来实现远程桌面的展…

P4 Qt如何添加qss样式表文件和添加图片资源

目录 前言 01 添加图片资源文件 02 添加qss文件 前言 &#x1f3ac; 个人主页&#xff1a;ChenPi &#x1f43b;推荐专栏1: 《C_ChenPi的博客-CSDN博客》✨✨✨ &#x1f525; 推荐专栏2: 《Qt基础_ChenPi的博客-CSDN博客》✨✨✨ &#x1f33a;本篇简介 &#xff1a;这一章…

JVM Optimization Learning(六)

目录 一、JVM Optimization 1、Shenandoah Shenandoah的使用方法 2、ZGC ZGC的版本更迭 ZGC的使用方法 ZGC的参数设置 3、JMH测试GC性能 一、JVM Optimization 1、Shenandoah Shenandoah是由Red Hat开发的一款低延迟的垃圾收集器&#xff0c;Shenandoah并发执行大部分…

机器人纯阻抗控制接触刚性环境(阻尼影响因素)

问题描述 在机器人学中&#xff0c;阻抗控制是一种常用的控制策略&#xff0c;用于管理机器人在与环境交互时的运动和力。阻抗控制背后的关键概念是将环境视为导纳&#xff0c;而将机器人视为阻抗。 纯阻抗控制接触刚性环境时&#xff0c;机器人的行为方式主要受其阻抗参数的…

【开源】基于Vue和SpringBoot的车险自助理赔系统

项目编号&#xff1a; S 018 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S018&#xff0c;文末获取源码。} 项目编号&#xff1a;S018&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 角色管理模块2.3 车…

Maven基础

目录 Maven坐标 坐标简介 主要组成 Maven依赖管理 配置依赖 依赖简介 配置依赖 依赖传递 依赖传递简介 排除依赖 依赖范围 生命周期 生命周期简介 执行指定生命周期 Maven坐标 坐标简介 Maven中的坐标是资源的唯一标识&#xff0c;通过该坐标可以唯一定位资…

Python开发运维:Python调用K8S API实现资源管理

目录 一、实验 1.Python操作K8S API获取资源 2.Python操作K8S API创建deployment资源 3.Python操作K8S API删除k8s资源 4.Python操作K8S API修改k8s资源 5.Python操作K8S API查看k8s资源 二、问题 1.Windows11安装kubernetes报错 2.Python通过调用哪些方法实现Pod和De…

在SpringData JPA 中实现对持久层的操作

1.导入依赖 hibernate 这个依赖自带实现JPA接口 <dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency><depen…

CrystalDiskInfo中文版(硬盘检测工具) v9.1.1.0 绿色汉化版-供大家学习研究参考

更新内容 重新支持三星SATA SSD寿命报告 增加对ZHITAI SC001的支持 新增SK hynix Gold S31支持 增加了KLEVV NEO N610的支持。 改进的Micron/Crucial SATA SSD支持 已更改 卸载程序将显示一个确认对话框&#xff0c;用于删除设置。 强大功能 1.拥有多国语言&#xff0c;…

045:Vue读取本地上传JSON文件,导出JSON文件方法

第045个 查看专栏目录: VUE ------ element UI 专栏目标 在vue和element UI联合技术栈的操控下&#xff0c;本专栏提供行之有效的源代码示例和信息点介绍&#xff0c;做到灵活运用。 &#xff08;1&#xff09;提供vue2的一些基本操作&#xff1a;安装、引用&#xff0c;模板使…

jquery手写广告轮播图,无限循环功能

说明 在很多情况下&#xff0c;我们都需要开发广告轮播图&#xff0c;当我们进行页面的功能开发时&#xff0c;采用轮播图来实现也行&#xff0c;但是很多情况下&#xff0c;我们只需要简单的控制轮播循环轮播展示即可&#xff0c;所以用jq开开发广告轮播波&#xff0c;自定义…

Idea 插件开发: Swing Designer设计器创建的组件全部为空问题记录

问题现象 通过Swing 设计器创建的对象, Swing组件全部是空的, 导致ToolWindowFactory工厂的实现类调用时候出现了空指针异常 如下方式创建的 问题分析 问题出现时候, 同时给我生成了一个createUIComponents的私有方法, 由于个人当时理解有误, 把他当成了初始化方法, 在里面…