Я хотел бы иметь возможность проверить, являются ли два вызываемых объекта одинаковыми или нет. Я бы предпочел идентификационную семантику (используя оператор «is»), но я обнаружил, что когда задействованы методы, происходит что-то другое.Как проверить функции на равенство или идентичность?
#(1) identity and equality with a method
class Foo(object):
def bar(self):
pass
foo = Foo()
b = foo.bar
b == foo.bar #evaluates True. why?
b is foo.bar #evaluates False. why?
Я воспроизвел как с Python 2.7 и 3.3 (CPython), чтобы убедиться, что это не деталь реализации старой версии. В других случаях тестирование идентичности работает, как ожидалось (интерпретатор сессия продолжила сверху):
#(2) with a non-method function
def fun(self):
pass
f = fun
f == fun #evaluates True
f is fun #evaluates True
#(3) when fun is bound as a method
Foo.met = fun
foo.met == fun #evaluates False
foo.met is fun #evaluates False
#(4) with a callable data member
class CanCall(object):
def __call__(self):
pass
Foo.can = CanCall()
c = foo.can
c == foo.can #evaluates True
c is foo.can #evaluates True
По вопросу How does Python distinguish callback function which is a member of a class?, функция обернута при связывании в качестве метода. Это имеет смысл и согласуется с рассмотренным выше случаем (3).
Есть ли надежный способ привязки метода к каким-либо другим именем, а затем сравнить их как объект, подлежащий вызову, или простая функция? Если «==» делает трюк, как это работает? Почему «==» и «есть» ведут себя по-другому в случае (1) выше?
Редактировать
Как @Claudiu отметил, что ответ на Why don't methods have reference equality? также ответ на этот вопрос.
Вы видели это? http://stackoverflow.com/questions/306313/python-is-operator-behaves-unexpectedly-with-integers Я думаю, что это может помочь немного понять, почему это происходит. – taronish4
Интересные вопросы, спасибо за публикацию. (+1) – NPE
Короче говоря, это связано с тем, что при вызове 'is' он проверяет идентификатор, а не само значение, а два неинстанцированных объекта не имеют одинакового идентификатора, а по сравнению с' == 'он проверяет значение объект, а не просто быстрый идентификационный чек. – Torxed