在pyyaml中表示具有相同基类的不同类的实例 [英] Represent instance of different classes with the same base class in pyyaml
问题描述
我有一些单元测试集,并希望将每个测试运行的结果存储为 YAML 文件以供进一步分析.YAML 格式的转储数据以多种方式满足我的需求.但是测试属于不同的套装,结果有不同的父类,这是我的例子:
I have some set of unittests and want to store results of each test run as YAML file for further analysis. Dump data in YAML format fit my needs in several ways. But tests belongs to different suits and results have different parent class, This is example of what I have:
>>> rz # shorthand for result
[<upstream_suite.fftest.SimpleTest testMethod=test_is_fsType_not_set>,
<upstream_suite.openfolder.UfoOpenTest testMethod=test_is_A>,
<upstream_suite.openfolder.UfoOpenTest testMethod=test_is_A_a_glyph_instance>,
<upstream_suite.openfolder.UfoOpenTest testMethod=test_is_ended_ufo>,
<upstream_suite.openfolder.UfoOpenTest testMethod=test_is_folder>,
<upstream_suite.openfolder.UfoOpenTest testMethod=test_is_fsType_eq_1>,
<upstream_suite.openfolder.UfoOpenTest testMethod=test_it_exists>]
# etc.
每个测试都可以有自己的父类.
Each test can have its own parent class.
>>> type(rz[0]) == type(rz[1])
False
我已经使用 __getstate__
方法为所有类添加了我自己的基类,但由于某种原因它不起作用:
I've added my own base class for all classes with __getstate__
method, but it is not working for some reason:
>>> rz[0].__getstate__()
{'targets': ['upstream'], 'methodDoc': 'Is the OS/2 table fsType set to 0?', 'methodName': 'test_is_fsType_not_set', 'tool': 'FontForge', 'name': 'upstream_suite.fftest'}
>>> yaml.safe_dump(rz[0])
*** RepresenterError: cannot represent an object: test_is_fsType_not_set (upstream_suite.fftest.SimpleTest)
文档说我可以为每个类做代表,所以我试了一下,写了这段代码:
Documentations say that I can make representer for each class, so I tried it and wrote this code:
import yaml
from somepath import MyTestCase
def repr_testcase(dumper, data):
return dumper.represent_mapping(u'tag:yaml.org,2002:map', {
'methodDoc': data._testMethodDoc,
'tool': data.tool,
'name': data.name,
'methodName': data._testMethodName,
'targets': data.targets,
})
# Register representer
yaml.SafeDumper.add_representer(MyTestCase, repr_testcase)
同时:
>>> isinstance(rz[0], MyTestCase)
True
即使在那之后 safe_dump
也不起作用.但是如果我做了这个技巧,那么它就会起作用并且我可以得到结果:
Even after that safe_dump
isn't working. But if I made this trick, then it works and I can get result:
>>> yaml.SafeDumper.add_representer(type(rz[0]), repr_testcase)
>>> print(yaml.safe_dump(rz[0]))
methodDoc: Is the OS/2 table fsType set to 0?
methodName: test_is_fsType_not_set
name: checker.upstream_suite.fontforge_suite.fftest
targets: [upstream]
tool: FontForge
但这意味着我需要记录所有可能出现的情况,也就是说……至少,看起来并不聪明.其实我真正的result
是更复杂的字典,不同地方的测试等等.
But that means that I need to register all possible occurrences, which is, well... at least, does not looks smart. Actually my real result
is more complex dictionary, tests harvested from different places, etc.
>>> for x in rz: yaml.SafeDumper.add_representer(type(x), repr_testcase)
>>> yaml.safe_dump(rz)
... here is expected result
所以,问题是,我在使用 __getstate__
时做错了什么,或者我如何让 pyyaml 与特定基类的所有实例一起工作,并且只有一个代表注册.
So, question is, what I'm doing wrong with __getstate__
or how I can make work pyyaml with all instances of particular base class with only one representer registration.
推荐答案
我找到了如何使这项工作发挥作用的方法.简短的回答是,还有另一种注册代表的方法,它称为 add_multi_representer
.所以修复是:
I found the way how to make this work. Short answer is that there is another way to register representer it called add_multi_representer
. So fix is:
# Change this line:
# yaml.SafeDumper.add_representer(MyTestCase, repr_testcase)
# to this line:
yaml.SafeDumper.add_multi_representer(MyTestCase, repr_testcase)
更新.多代表允许实现我想要实现的目标:为基类注册代表.
Upd. Multi representer allow to make what I was trying to achieve: register representer for base class.
这篇关于在pyyaml中表示具有相同基类的不同类的实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!