我有一个类的属性的字典列表,它使用@property getter和setter实现。然而,我希望有一个条件getter或具有相同名称的替代实现。
我的班级和@property有getter和setter运行和单元测试。唯一缺少的是用于过滤目的的pythonic实现条件getter。
我查看了官方文档,谷歌搜索,非常简要地看了一些Pandas源代码。
# python v3.7.2
# simplified code
class MyClass:
def __init__(self)
self.uuid = str(uuid.uuid4())
self.my_dict = []
@property
def mydict(self)
return self._mydict
@mydict.setter
def mydict(self, inputdict)
self._mydict.append({
'target': inputdict.get('target').uuid})
A,B,C = MyClass()
A.mydict = {'target':B}
打印(A.mydict)
[{'target':B.uuid}]
A.mydict = {'target':C}
打印(A.mydict)
[{'target':B.uuid},{'target':C.uuid}]
而且我希望拥有
打印(A.mydict(目标= B))
[{'target':B.uuid}]
这需要额外的编码来处理getter中的假设关键字参数
TypeError:'list'对象不可调用
正如评论员所建议的,并且由于属性和方法之间的故意差异,并且由于我正在处理的事情具有数据和行为,我为此创建了一个专门的类。
我发布了行为的类和单元测试。最有可能的是,这段代码很容易出错,但它可以完成当前版本的宠物项目。欢迎任何有关可用性和扩展的提示和潜在问题。
class Correspondence(dict):
"""A class for Correspondence data structure, see Chapter 2 of the book."""
def update(self, *args, **kwargs):
"""Update the correspondence object with the unique keys."""
try:
keyid = args[0]['target'] + args[0]['source'] + args[0]['condition']
self[keyid] = args[0]
except KeyError:
raise TypeError('The input should contain source, target, \
condition and truthvalue as keys of the input dictionary')
def filter(self, source=None, target=None, condition=None, truthvalue=None):
"""Filter Correspondence object. (target ⇐ source))
Input:
source: filtering condition, source
target: filtering condition, target
condition: filtering conidtion, correspondence condition
truthvalue: filtering condition, truthvalue excluding
Output:
output: a Correspondence instance
"""
filters = {
'source': source,
'target': target,
'condition': condition,
'truthvalue': truthvalue}
filters = {k: v for k, v in filters.items() if v is not None}
if not bool(filters):
return self
else:
_correspondence = copy.deepcopy(self)
# iterate over filters, followed by iteration over items
# if the conditions are not satisfied, then items are removed
# matrix-based computation would be more efficient,
# but would do for now unless performance issues
for filter_key, filter_value in filters.items():
for key, value in self.items():
if value[filter_key] is not filter_value:
del _correspondence[key]
return _correspondence
单元测试
def test_correspondence_structure_and_methods(self):
# check if correspondence has the right structure
BA_correspondence = {
'source': 'A.uuid',
'target': 'B.uuid',
'condition': 'the condition',
'truthvalue': 'true'}
CA_correspondence = {
'source': 'A.uuid',
'target': 'C.uuid',
'condition': 'the condition',
'truthvalue': 'true'}
CA_correspondence_wrong = {
'sources': 'A.uuid', # the key should be "source"
'target': 'C.uuid',
'condition': 'the condition',
'truthvalue': 'true'}
BA_correspondence_upd = {
'source': 'A.uuid',
'target': 'B.uuid',
'condition': 'the condition',
'truthvalue': 'unverifiable'}
correspondence = fabric.Correspondence()
# test if Correspondence.update() processes the right data
self.assertRaises(
TypeError,
correspondence.update,
CA_correspondence_wrong)
correspondence.update(BA_correspondence)
# (B ⇐ A)
self.assertDictEqual(
{'B.uuidA.uuidthe condition': BA_correspondence},
correspondence)
# (B ⇐ A) ⋅ (C ⇐ A)
correspondence.update(CA_correspondence)
self.assertDictEqual(
{
'B.uuidA.uuidthe condition': BA_correspondence,
'C.uuidA.uuidthe condition': CA_correspondence},
correspondence)
# updated truthvalue with the same source, target, and condition
# (B ⇐ A) ⋅ (C ⇐ A)
correspondence.update(BA_correspondence_upd)
self.assertDictEqual(
{
'B.uuidA.uuidthe condition': BA_correspondence_upd,
'C.uuidA.uuidthe condition': CA_correspondence},
correspondence)
# filter correspondence
self.assertDictEqual(
{
'B.uuidA.uuidthe condition': BA_correspondence_upd,
'C.uuidA.uuidthe condition': CA_correspondence},
correspondence.filter())
self.assertDictEqual(
{
'B.uuidA.uuidthe condition': BA_correspondence_upd},
correspondence.filter(target='B.uuid'))
self.assertDictEqual(
{
'B.uuidA.uuidthe condition': BA_correspondence_upd,
'C.uuidA.uuidthe condition': CA_correspondence},
correspondence.filter(source='A.uuid'))
self.assertDictEqual(
{
'B.uuidA.uuidthe condition': BA_correspondence_upd,
'C.uuidA.uuidthe condition': CA_correspondence},
correspondence.filter(condition='the condition'))
self.assertDictEqual(
{
'C.uuidA.uuidthe condition': CA_correspondence},
correspondence.filter(truthvalue='true'))
self.assertDictEqual(
{
'B.uuidA.uuidthe condition': BA_correspondence_upd},
correspondence.filter(source='A.uuid', truthvalue='unverifiable'))
self.assertDictEqual(
{
'B.uuidA.uuidthe condition': BA_correspondence_upd},
correspondence.
filter(source='A.uuid').filter(truthvalue='unverifiable'))