복붙노트

[PYTHON] 메소드가 참조 평등을 갖는 이유는 무엇입니까?

PYTHON

메소드가 참조 평등을 갖는 이유는 무엇입니까?

내가 사용하는 경우 서로 평등 한 방법에 의존하는 버그가있었습니다. 그것은 사실이 아닙니다.

>>> class What(object):
    def meth(self):
        pass

>>> What.meth is What.meth
False
>>> inst = What()
>>> inst.meth is inst.meth
False

왜 그런 경우입니까? 그것은 일반적인 기능을 위해 작동합니다 :

>>> def func():
    pass

>>> func is func
True

해결법

  1. ==============================

    1.메서드 개체는 액세스 할 때마다 만들어집니다. 함수는 설명 자의 역할을하여 .__ get__ 메서드가 호출 될 때 메서드 객체를 반환합니다.

    메서드 개체는 액세스 할 때마다 만들어집니다. 함수는 설명 자의 역할을하여 .__ get__ 메서드가 호출 될 때 메서드 객체를 반환합니다.

    >>> What.__dict__['meth']
    <function meth at 0x10a6f9c80>
    >>> What.__dict__['meth'].__get__(None, What)
    <unbound method What.meth>
    >>> What.__dict__['meth'].__get__(What(), What)
    <bound method What.meth of <__main__.What object at 0x10a6f7b10>>
    

    == 동등 테스트를 대신 사용하십시오.

    .im_self 및 .im_func 특성이 동일한 경우 두 메서드가 동일합니다. 메서드가 동일한 기본 함수를 나타내야하는지 테스트해야하는 경우 해당 im_func 특성을 테스트합니다.

    >>> What.meth == What.meth     # unbound methods (or functions in Python 3)
    True
    >>> What().meth == What.meth   # unbound method and bound method
    False
    >>> What().meth == What().meth # bound methods with *different* instances
    False
    >>> What().meth.im_func == What().meth.im_func  # functions
    True
    
  2. ==============================

    2.Martijn은 새로운 메소드가 .__ get__에 의해 생성 된 객체이기 때문에 주소 포인터가 평가와 같지 않음을 올바르게 알고 있습니다. ==를 사용하면 Python 2.7에서 의도 한대로 평가됩니다.

    Martijn은 새로운 메소드가 .__ get__에 의해 생성 된 객체이기 때문에 주소 포인터가 평가와 같지 않음을 올바르게 알고 있습니다. ==를 사용하면 Python 2.7에서 의도 한대로 평가됩니다.

    Python2.7
    class Test(object):
        def tmethod(self):
            pass
    
    >>> Test.meth is Test.meth
    False
    >>> Test.meth == Test.meth
    True
    
    >>> t = Test()
    >>> t.meth is t.meth
    False
    >>> t.meth == t.meth
    True
    

    그러나 인스턴스에서 참조 된 메소드는 인스턴스의 메소드와 함께 수행 된 자체 참조로 인해 클래스에서 참조 된 메소드와 동일하지 않습니다.

    >>> t = Test()
    >>> t.meth is Test.meth
    False
    >>> t.meth == Test.meth
    False
    

    파이썬 3.3에서 메서드에 대한 is 연산자는 ==와 동일하게 동작하므로이 예제에서 예상되는 동작을 얻습니다. 이것은 __cmp__이 사라지고 Python 3에서보다 깔끔한 메소드 객체 표현이 된 결과입니다. 메소드는 이제 __eq__을 가지며 참조는 실행 중 객체가 아닙니다. 따라서이 동작은 Python 2가 기대하지 않는 한 기대할 수 있습니다.

    Python3.3
    >>> Test.meth is Test.meth
    True
    >>> Test.meth == Test.meth
    True
    >>> Test.meth.__eq__(Test.meth)
    True
    
  3. from https://stackoverflow.com/questions/15977808/why-dont-methods-have-reference-equality by cc-by-sa and MIT license