Вы правы. Там нет информации о положении для примитивных типов. Похоже, вы уже рассмотрели доступные варианты.
То, что было бы легко реализовать, - это добавить учет позиции непосредственно в textX всех атрибутов в виде специальной структуры для каждого созданного объекта (например, диктовку, обозначенную именем атрибута). Это должно быть легко реализовано, чтобы вы могли зарегистрировать запрос функции в трекере ошибок, если хотите.
В прошлом проводилась работа по поддержке полных языковых услуг для языков на основе textX. Идея состоит в том, чтобы получить все функции, которые вы ожидаете от приличного редактора кода / IDE для любого языка, указанного с использованием textX. Работа на некоторое время замерла, но недавно возобновилась как полная перезапись. Это должно быть официально поддержано командой textX. Вы можете следить за прогрессом здесь . Хотя в данный момент в проекте не упоминается подсветка синтаксиса, он включен в нашу повестку дня.
Вы должны реализовать метод __ eq __
:
class MyClass:
def __init__(self, foo, bar):
self.foo = foo
self.bar = bar
def __eq__(self, other):
if not isinstance(other, MyClass):
# don't attempt to compare against unrelated types
return NotImplemented
return self.foo == other.foo and self.bar == other.bar
Теперь он выводит:
>>> x == y
True
Обратите внимание, что реализация __ eq __
автоматически создаст экземпляры вашего класса unhashable, что означает, что они не могут храниться в наборах и dicts. Если вы не моделируете неизменяемый тип (например, если атрибуты foo
и bar
могут изменять значение в течение времени жизни вашего объекта), то рекомендуется просто оставить ваши экземпляры как нехешируемые. .
Если вы моделируете неизменяемый тип, вам также следует реализовать ловушку модели данных __ hash __
:
class MyClass:
...
def __hash__(self):
# necessary for instances to behave sanely in dicts and sets.
return hash((self.foo, self.bar))
Общее решение, подобное идее перебора __ dict __
и сравнения значений , не рекомендуется - он никогда не может быть действительно общим, потому что __ dict __
может содержать несопоставимые или нехешируемые типы.
NB: имейте в виду, что до Python 3 вам может потребоваться использовать __ cmp __
вместо __ eq __
. Пользователи Python 2 могут также захотеть реализовать __ ne __
, поскольку разумное поведение по умолчанию для неравенства (т.е. инвертирование результата равенства) не будет автоматически создано в Python 2.
В зависимости от Вашего конкретного случая Вы могли сделать:
>>> vars(x) == vars(y)
True
Я записал это и поместил его в test/utils
модуль в моем проекте. Для случаев, когда не класс, просто запланируйте старый dict, это пересечет оба объекта и удостоверится
Его большое... его не сексуальный ..., но о boi делает он работает!
def assertObjectsEqual(obj_a, obj_b):
def _assert(a, b):
if a == b:
return
raise AssertionError(f'{a} !== {b} inside assertObjectsEqual')
def _check(a, b):
if a is None or b is None:
_assert(a, b)
for k,v in a.items():
if isinstance(v, dict):
assertObjectsEqual(v, b[k])
else:
_assert(v, b[k])
# Asserting both directions is more work
# but it ensures no dangling values on
# on either object
_check(obj_a, obj_b)
_check(obj_b, obj_a)
можно очистить его немного путем удаления _assert
и просто использования простой assert
, но затем сообщение, которое Вы получаете, когда это перестало работать, очень бесполезно.
Необходимо реализовать метод __eq__
:
class MyClass:
def __init__(self, foo, bar, name):
self.foo = foo
self.bar = bar
self.name = name
def __eq__(self,other):
if not isinstance(other,MyClass):
return NotImplemented
else:
#string lists of all method names and properties of each of these objects
prop_names1 = list(self.__dict__)
prop_names2 = list(other.__dict__)
n = len(prop_names1) #number of properties
for i in range(n):
if getattr(self,prop_names1[i]) != getattr(other,prop_names2[i]):
return False
return True
Вы переопределите расширенные операторы сравнения в вашем объекте.
class MyClass:
def __lt__(self, other):
# return comparison
def __le__(self, other):
# return comparison
def __eq__(self, other):
# return comparison
def __ne__(self, other):
# return comparison
def __gt__(self, other):
# return comparison
def __ge__(self, other):
# return comparison
Примерно так:
def __eq__(self, other):
return self._id == other._id
Реализуйте метод __ eq __
в своем классе; что-то вроде этого:
def __eq__(self, other):
return self.path == other.path and self.title == other.title
Изменить: если вы хотите, чтобы ваши объекты сравнивались равными тогда и только тогда, когда они имеют одинаковые словари экземпляров:
def __eq__(self, other):
return self.__dict__ == other.__dict__
Экземпляр класса по сравнению с == оказывается не равным. Лучший способ - передать функцию cmp вашему классу, который будет делать все это.
Если вы хотите провести сравнение по содержимому, вы можете просто использовать cmp (obj1, obj2)
В вашем случае cmp (doc1, doc2) он вернет -1, если контент по содержанию одинаков.
При сравнении экземпляров объектов, вызывается функция __ cmp __
.
Если оператор == не работает для вас по умолчанию, вы всегда можете переопределить функцию __ cmp __
для объекта.
] Редактировать:
Как было указано, функция __ cmp __
устарела с версии 3.0.
Вместо этого вам следует использовать методы «богатого сравнения» .