Я придумал альтернативное решение, которое, возможно, менее корректно, но ответы позволят мне решить проблему так, как я изначально хотел.
Мое решение использует служебный класс, который можно использовать в качестве члена класса.или как миксин для класса, чтобы обеспечить функции полезности удобным способом.Ниже функции _equals
и is_close
определены в других местах, поскольку их реализации помимо точки.
class EquivalenceUtil(object):
def __init__(self, equal_comparator=_equals, inexact_comparator=is_close):
self.equals = equal_comparator
self.default_comparator = inexact_comparator
def check_equivalence(self, obj_a, obj_b, exact_match=False, **kwargs):
return self.equals(obj_a, obj_b, **kwargs) if exact_match else self.default_comparator(obj_a, obj_b, **kwargs)
Это простой класс, который можно использовать так:
class BBOX(object):
_equivalence = EquivalenceUtil()
def __init__(self, **kwargs):
...
@classmethod
def are_equivalent(cls, bbox_a, bbox_b, exact_match=False):
"""Test for equivalence between two BBOX's."""
bbox_list = bbox_a.as_list
other_list = bbox_b.as_list
for _index in range(0, 3):
if not cls._equivalence.check_equivalence(bbox_list[_index],
other_list[_index],
exact_match=exact_match):
return False
return True
Это решение более непрозрачно для пользователя о том, как все проверяется за кулисами, что важно для моего проекта.Кроме того, он довольно гибкий и может быть многократно использован внутри класса в разных местах и легко добавлен в новый класс.
В моем исходном примере код может выглядеть так:
class TileGrid(object):
def __init__(self, **kwargs):
...
@staticmethod
def are_equivalent(grid1, grid2, check_name=False, exact_match=False):
if check_name:
return grid1.name == grid2.name
# Check minimum resolutions if they are specified
if 'min_res' in grid1 and 'min_res' in grid2 and not cls._equivalence.check_equivalence(grid1['min_res'], grid2['min_res'], exact_match=exact_match):
return False
# Compare the bounding boxes of the two grids if they exist in the grid
if 'bbox' in grid1 and 'bbox' in grid2:
return BBOX.are_equivalent(grid1.bbox, grid2.bbox, exact_mach=exact_match)
return False
Я не могу рекомендовать этот подход в общем случае, потому что я не могу не чувствовать, что в нем есть какой-то запах кода, но он делает именно то, что мне нужно, и решит очень много проблем для моей текущей кодовой базы.У нас есть конкретные требования, это конкретное решение.Решение от chepner, вероятно, лучше всего подходит для общего случая, когда пользователь может решить, как функция должна проверять эквивалентность.