자세한 내용은 this blog post을 참조하십시오. 하지만 여기서 요약 할 수 있습니다.
핵심은 바인딩 된 방법을 이해하는 것입니다. 바운드 메소드는 실제 함수 오브젝트와 그것이 바인드 된 인스턴스를 보유하는 오브젝트입니다. 이런 식으로 뭔가 :
>>> class C:
... def foo(self):
... print(self)
>>> C.foo
<function __main__.foo>
>>> c = C()
>>> c.foo
<bound method C.foo of <__main__.C object at 0x10ab90a90>>
>>> c.foo.__func__
<function __main__.foo>
>>> c.foo.__func__ is C.foo, c.foo.__self__ is c
(True, True)
을 그리고 당신도 수동으로 구성 할 수 있습니다 :
>>> import types
>>> f = types.MethodType(C.foo, 2)
>>> f
<bound method int.foo of 2>
>>> f()
2
당신이 주변을 전달하고이를 검사 할 수 있도록
class BoundMethod(object):
def __init__(self, function, instance):
self.__func__ = function
self.__self__ = instance
def __call__(self, *args, **kwargs):
return self.__func__(self.__self__, *args, **kwargs)
바인딩 방법, 일류 개체
(위의 Python 클래스는 분명히 실제 코드가 아니지만 멀리 떨어져있는 것은 아니며 바인드 된 메서드 나 호출 할 수없는 메서드를 바인딩하려는 바보 같은 작업을 수행하면 대부분 동일한 오류가 발생합니다.)
따라서 c.foo
은 c
에 어떻게 끝나나요? 이를 실제로 이해하려면 설명자를 이해해야합니다. 그러나 짧은 버전은 다음과 같습니다.
거의 모든 유형의 파이썬에는 추가 방법 __get__
이 있습니다. 그리고 이것은 속성 액세스에 사용됩니다. 당신이 c.foo
를 입력 할 때 기본적으로,이 같은 무언가를 (기본 클래스, 슬롯, getattr 오버라이드 (override) 등 무시) :
이
try:
return c.__dict__['foo']
except KeyError:
value = type(c).__dict__['foo']
try:
return value.__get__(c)
except AttributeError:
return value
함수 객체의 __get__
방법은 바인딩 된 메서드를 반환합니다 (인수에 바인딩) .
그래서, 분명히 다시 예 약
A
B(A()).show_name
때문에이
A
인스턴스에 바인딩 물건을
B(A()).show_name()
인쇄 외출 ...하지만 어떻게 그런 일이?
음,이를 통해 추적하자 : 당신의 __init__
기능 내부
>>> a = A()
>>> b = B(a)
>>> b.show_name
을, 이렇게 : 단지 self.show_name
변수 일반 인스턴스에 이미 바인딩 방법 a.show_name
을 복사하는 것
self.show_name = a.show_name
. 따라서 나중에 b.show_name
을 조회하면 동일한 바인딩 방법 인 a
에 바인딩됩니다. 다시 바인드하려면 다음과 같이 수동으로해야합니다.
self.show_name = types.MethodType(a.show_name.__func__, self)
이것은 몇 달 전의 질문 중 하나이지만, 찾을 수 없습니다. 저는 [블로그 게시물] (http://stupidpythonideas.blogspot.com/2013/06/how-methods-work.html)을 찾을 수 있습니다. 답변을 설명하는 데 도움이되었습니다. – abarnert
@abarnert 멋진 기사. 어떤 타입 에든'__call__' 메쏘드를 추가하고 호출 가능하도록 할 수 있는지 전혀 몰랐습니다. –
@ 제레미 : 필자는 파이썬 3.x를 함수로 사용하기 때문에 여기에서 파이썬 3.x를 사용하고 있다고 가정합니다. 그러나 출력을 보면 파이썬 2.x처럼 보입니다. 2.x가 어떻게 작동하는지 설명하기 위해 내 대답을 편집하길 원하십니까? (좀 더 복잡하고 특수한 속성의 이름은 다르지만 기본 아이디어는 같습니다.) – abarnert