当前位置: 首页 > 面试题库 >

如何记住**?

徐昕
2023-03-14
问题内容

我还没有找到一种记忆带有关键字参数(即某种类型)的函数的既定方法

def f(*args, **kwargs)

因为通常情况下,备注器具有adict来缓存给定一组输入参数的结果,并且kwargs是a
dict,因此不可哈希。我尝试过,在这里讨论之后,使用

(args, frozenset(kwargs.items()))

作为缓存的键dict,但这仅在其中的值kwargs可哈希化时有效。此外,正如下面的答案所指出的那样,frozenset它不是有序的数据结构。因此,此解决方案可能更安全:

(args, tuple(sorted(kwargs.items())))

但是它仍然无法应付不可散列的元素。我见过的另一种方法是使用cache键中的string表示形式kwargs

(args, str(sorted(kwargs.items())))

我看到的唯一缺点是散列可能很长的字符串的开销。据我所见,结果应该是正确的。有人能发现后一种方法有任何问题吗?以下答案之一指出,对于关键字自变量的值,这假定__str____repr__函数的某些行为。这似乎是个制止者。

是否有另一种更成熟的方式来实现能够处理**kwargs和不可散列的参数值的备注?


问题答案:
key = (args, frozenset(kwargs.items())

这是您无需假设数据即可做到的“最佳”结果。

但是,似乎可以对词典执行记忆(虽然有点不寻常),但是如果需要,可以特例。例如,您可以frozenset(---.items())在复制字典时递归地应用。

如果这样做sorted,则可能会遇到键无法排序的情况。例如,“
子集和相等性比较不能推广到完整的排序函数。例如,任何两个不相交的集合都不相等,也不是彼此的子集,因此以下所有内容均返回False:ab。因此,集合可以无法实现
cmp ()方法。

>>> sorted([frozenset({1,2}), frozenset({1,3})])
[frozenset({1, 2}), frozenset({1, 3})]

>>> sorted([frozenset({1,3}), frozenset({1,2})]) # THE SAME
[frozenset({1, 3}), frozenset({1, 2})] # DIFFERENT SORT RESULT

# sorted(stuff) != sorted(reversed(stuff)), if not strictly totally ordered

编辑: 伊格纳西奥说:“虽然您不能对任意字典使用sorted(),但kwargs将具有str键。”
这是完全正确的。因此,这对于键来说不是问题,但是如果您(或不太可能代表)依赖某种方式进行排序,则可能需要记住一些值。

关于使用str

它是这样 大多数
数据将很好地工作,但它是可能的对手(例如,在安全漏洞上下文)制作一个碰撞。您介意这不是一件容易的事,因为大多数默认值都repr使用许多良好的分组和转义。实际上,我找不到这种碰撞。但是,草率的第三方或不完整的repr实现都是可能的。

还请考虑以下事项:如果您存储像((<map object at 0x1377d50>,), frozenset(...))和这样的键((<list_iterator object at 0x1377dd0>,<list_iterator object at 0x1377dd0>), frozenset(...)),则只需调用相同的项,缓存就会无限增长。(您也许可以使用正则表达式解决此问题…)并且尝试使用生成器会弄乱您正在使用的函数的语义。尽管如果您想记住is-style平等而不是==-style平等,则这可能是理想的行为。

同样str({1:object()})在解释器中执行类似的操作,每次都会在内存中相同位置返回一个对象!我认为这是工作中的垃圾收集器。这将是灾难性的,因为如果您碰巧正在进行哈希处理,<some object at 0x???????>并且稍后(由于进行垃圾回收)碰巧在相同的内存位置创建了相同类型的对象,则从备注化函数中将得到不正确的结果。如前所述,一种可能真正棘手的解决方法是使用正则表达式检测此类对象。



 类似资料:
  • 我将事件发送到AWS Kinesis,这些事件由AWS lambda函数处理。但是,如果lambda抛出一些错误,则不会丢弃记录,并且会一次又一次地进行处理,从而阻止处理新记录。 我宁愿跳过错误的记录,消化新的记录。我不知道该怎么做。 lambda函数捕获任何异常,因此不应给出任何执行错误。 下面是python中的片段。 我知道lambda应该在“保留”期间重试(默认为24小时),但我希望放弃并最

  • 我有一个带有普罗米修斯的k8s集群和几个带有web应用程序的豆荚。我想从这些网络应用程序中收集度量标准。我使用Prometheus blackbox_exporter来实现这一点。 我配置了服务监视器,部署,工作由普罗米修斯操作员。普罗米修斯收集了度量,但我无法区分它们。例如, 我应该做什么来为每个endpoint添加额外的标签? 如何向probe_success度量标准添加诸如target之类的

  • 问题内容: 因此,我已经构建了该程序来构建不同的楼梯案例。本质上,问题是:给定整数N,您可以建立楼梯的几种不同方式。确保N大于3且小于200。任何先前的步骤都不能大于其后续步骤,否则会破坏楼梯的目的。 所以给定N = 3,您可以建立一个楼梯:2步,然后再步1步 给定N = 4,您可以建立一个楼梯:3步,然后再步1步 给定N = 5,您可以构建两个楼梯:3步,然后2步,或4步,然后1步。 我的方法在

  • 问题内容: 我已经开始在一个拥有数以百计的表和视图的数据库的地方工作,所有这些表和视图都具有隐秘的名称,只有很少的元音,并且没有文档。它们也不允许对数据库架构进行无谓的更改,我也不能触摸任何数据库,除非要在我自己的计算机上进行测试(该数据库会被删除并定期重新创建),因此我无法添加对任何人都有用的注释。 我尝试使用“ Toad”创建一个ER图,但是连续运行48小时后,它仍然看不到任何可见的东西,我需

  • 我正在使用Jupyter笔记本编写Python 2代码。我将其调用为: 同时,我使用IPython控制台,启动时使用: 我的问题是,Jupyter历史被保存,并且与IPython历史混合在一起。我根本不想要Jupyter笔记本的历史记录-有没有办法禁用它,同时保留IPython**历史记录? 平台:win32 更新: 我尝试过使用建议的设置摘要方法。但是,当我在配置中输入“c.Session.di

  • 问题内容: 好的,这是真实的情况:我正在编写一个应用程序,并且有一个表示某种类型文件的类(在我的情况下,这是照片,但是细节与问题无关)。Photograph类的每个实例对于照片的文件名应该是唯一的。 问题是,当用户告诉我的应用程序加载文件时,我需要能够确定文件何时已加载,并使用该文件名的现有实例,而不是在同一文件名上创建重复的实例。 对我来说,使用记忆化似乎是一种好情况,并且有很多这样的例子,但是

  • 我正在为spring调度器使用cron表达式,表达式的值由Springbean使用spel动态提供。 一切都正常工作,唯一的问题是我想记录调度程序何时触发,因为cron表达式是由另一个bean在运行时提供的。所以只想知道是否将通过文件提供的正确表达式映射到属性bean。

  • 我正在使用querySelector获得一个div元素,并且能够更改按钮名称,但是我还想插入一个span标记。好心的帮助。 我想把“标准”包装在span标记中。请帮帮忙。