基本Python数据结构接口测试

2024-05-16 22:11:34 发布

您现在位置:Python中文网/ 问答频道 /正文

一个相当小的问题:有没有人知道一套预先准备好的Python单元测试,这些测试只检查一个类是否符合标准Python数据结构接口之一(例如,列表、集合、字典、队列等)。写它们并不难,但如果有人已经这样做了,我不想费心去写。这似乎是一个很基本的功能,有人可能已经做过了。在

该用例是由于与平台相关的不同限制,我使用工厂模式来创建数据结构。因此,我需要能够测试生成的对象是否仍然符合表面上的标准接口。另外,我应该注意到,“conform”的意思是测试不仅要检查接口函数是否存在,还要检查它们是否工作(例如,可以设置和检索映射中的值)。最好是Python2.7测试。在


Tags: 对象功能数据结构列表字典队列工厂模式
2条回答

首先,“标准Python数据结构接口”不是列表、集合、字典、队列等,它们是接口的具体实现。(而且queue甚至不是一个数据结构,在您所想的它的显著特征是它的操作是原子的,并且put和{}可选地在Condition上同步,依此类推。)

无论如何,接口是用五种不同的不完全兼容的方式定义的。在


<>文件的Built-in Types部分描述了迭代器类型、序列类型等的含义。然而,这些并不像您期望的那样严格,至少在使用时,例如,C++或java。在

我不知道有任何针对这种东西的测试,所以我认为你必须从头开始构建它们。在


collections模块包含定义接口的Collections Abstract Base Classes,并提供通过^{} module注册“虚拟子类”的方法。因此,您可以通过继承collections.Mapping,或调用collections.Mapping.register来声明“我是一个映射”。但这并不能证明你是一个映射,只是你声称是。(如果您从Mapping继承,它还充当mixin,帮助您通过在__getitem__上实现__contains__来完成接口。)

如果你想测试ABC的意思,defuz的答案非常接近,我想他或其他人可以完成它。在


cpythonc API定义了一个Abstract Objects Layer。虽然这并不是语言的权威,但很明显,C-API协议和语言级接口应该匹配。与后者不同的是,前者有严格的定义。当然,来自CPython 2.7的源代码,也许还有PyPy等其他实现可能会有所帮助。在

CPython附带了一些测试,但实际上,它们是为了测试从C调用PyMapping_GetItem正确调用Python中的mymapping.__getitem__,这实际上与您想要测试的内容是相切的,所以我认为这不会有多大帮助。在


实际的具体类在协议之上有额外的接口,您可能想测试这些接口,但这很难描述。尤其是__new____init__方法的工作方式通常很重要。实现Mapping协议意味着某人可以构造一个空的Foo实例,并用foo[key] = value向其添加项,但这并不意味着有人可以构造Foo(key=value),或Foo({key: value})或{}。在

对于本例,所有标准Python实现都附带了现有测试。CPython附带了一个非常广泛的测试套件,包括^{}之类的东西。PyPy运行所有(Python级别)CPython测试,以及一些额外的测试。在

显然,您必须修改这些测试以在任意类上运行,而不是硬编码到测试中的类,而且您可能还必须修改它们以处理您选择的任何定义。另外,他们可能比你要求的测试更多。你只想知道一个类是否符合协议,而不是它的方法是否正确,对吗?但我仍然认为这是一个很好的起点。在


最后,C API定义了一个Concrete Objects Layer,尽管它不是权威的,但它与前面的定义相匹配,并且定义更严格。在

不幸的是,这个测试的肯定不会对您非常有用,因为它们检查的是PyDict_Check和{}是否在您的类上工作,而这对于纯Python中定义的任何映射都是无效的。在


如果您确实为这些定义构建了一些完整的东西,我强烈建议您将其放到PyPI上,并将其发布到python列表中,这样您就可以得到反馈(和bug报告)。在

基于ABC模块的标准模块collections中有{a1}。在

必须从这些类继承类,以确保类与标准行为相对应:

import collections

class MyDict(collections.Mapping):
    ...

此外,还可以测试不明显继承抽象类的已存在类:

^{pr2}$

相关问题 更多 >