2012-12-07 2 views
1

메서드를 재정의하지 않고 싱글 톤 클래스에서 함수 호출을 캡처하려고합니다. 파이썬 캡처 메서드 호출 및 매개 변수

은 현재 내가이 일을 해요 :

class MyClass 
    oldMethod = None 

    def __init__(self): 
     c = Class.Instance() 
     self.oldMethod = c.Method #make a copy to the pointer of the original function 
     c.Method = self.NewMethod #redirect it 

    def NewMethod(self, x, a): 
     self.oldMethod(x, a) #call the old function 
     #My Stuff 

내가 '이벤트'(메소드 호출되는)이 메소드 호출의 매개 변수를 캡처하기 위해 노력하고있어. '수동적으로'그것을 포착하고 매개 변수를 듣고 얻으라고 말하는 다른 방법이 있습니까?

참고 : 싱글 톤 클래스의 코드에 액세스 할 수 없습니다. 당신은 winpdb을 사용할 수

감사

+0

이 질문을보십시오 : http://stackoverflow.com/questions/4723717/how-to-intercept-instance-method-calls – Blender

+0

링크를 보내 주셔서 감사합니다. 나는 'Class'메서드를 직접 호출하고 싶지 않다. 클래스가 이미 생성되었으므로 클래스가 들어올 때 호출 할 때 'Class'의 하위 클래스를 만들지 않고 호출 할 때 매개 변수를 가져오고 싶다. – Tempster102

+0

바로 그 코드가하는 것입니다. 래퍼 클래스는 래핑 된 인스턴스를 호출하고 매개 변수를 인쇄합니다. – Blender

답변

0

는 파이썬을위한 그래픽 디버거를 사용하기 좋은 쉽습니다. 그래서 당신은 문제의 파이썬 스크립트를 열고,보고 싶은 클래스에 어떤 방법 으로든 breakpoint을 설치하십시오. 이 시점에서 일시 중지되고 변수의 상태와 해당 메소드를 호출 할 때마다 표시되지 않는 내용이 표시됩니다.

+0

안녕하세요, 디버깅하는 동안 정상 작동 중에 함수 호출을 가로 채고 싶습니다. 고마워! – Tempster102

1

디버깅하는 동안뿐만 아니라 일반적인 작업 중에 메서드 호출을 가로 채길 원한다고 언급했습니다. 이 솔루션은 다른 접근법이고 다른 대답은 원래 개체에 대한 모든 호출에 대한 래퍼 일종의 새 개체를 만들기위한 Proxy pattern 접근 방식을 사용합니다. 프록시 수준에서 필요에 따라 호출을 기록하고 모니터링 할 수 있습니다.

person.py

내가 person 모듈에 Person라는 예제 클래스를 생성 한 코드를 설명합니다. 이것이 코드를 수정할 수없는 모듈 인 척 할 수 있습니다.

class Person(object): 
    def __init__(self, name=None): 
     self.name = name 

    def greet(self, greeting='hello'): 
     print '%s %s' % (greeting, self.name) 

    def __repr__(self): 
     return "Person(%r)" % self.name 

코드에서 example.py

우리는 프록시 개체 대신 Person의 사용 때와 같은 동작을하고, 인사 방법에 대한 모든 호출을 로그의 추가 행동을 가지고 ProxyPerson라는 만들 이하 . 나중에 *args, **kwargs을 사용하므로 Person이 다른 서명을 가질 수 있지만 변경 사항이 적용되면 코드가 손상되지 않습니다.

import person 

class ProxyPerson(person.Person): 
    def greet(self, *args, **kwargs): 
     print '--- greet() self=%r args=%r kwargs=%r' % (self, args, kwargs) 
     super(ProxyPerson, self).greet(*args, **kwargs) 

#person.Person = ProxyPerson #uncomment to monkey patch Person 

jack, jill = person.Person('Jack'), ProxyPerson('Jill') 
for p in jack, jill: 
    p.greet() 
    p.greet('hi') 
    p.greet(greeting='why hello') 

일본어 Person 클래스를 사용하는 경우 또는 ProxyPerson 사용할 때 출력은 아래의 실행에서의 차이를 나타낸다

정규 출력. 예제에는 위치 인수가없고 위치 인수가 있고 마지막으로 키워드 인수가있는 호출도 포함됩니다.

hello Jack 
hi Jack 
why hello Jack 
--- greet() self=Person('Jill') args=() kwargs={} 
hello Jill 
--- greet() self=Person('Jill') args=('hi',) kwargs={} 
hi Jill 
--- greet() self=Person('Jill') args=() kwargs={'greeting': 'why hello'} 
why hello Jill 

원숭이 패치 출력

마지막으로 하나 Monkey patchperson.Person 클래스는 ProxyPerson를 가리 키도록 할 수 있습니다. 원숭이 패치 라인을 example.py으로 해설함으로써이 접근법을 시험해 볼 수 있습니다. 이 경우 출력은 다음과 같습니다.

--- greet() self=Person('Jack') args=() kwargs={} 
hello Jack 
--- greet() self=Person('Jack') args=('hi',) kwargs={} 
hi Jack 
--- greet() self=Person('Jack') args=() kwargs={'greeting': 'why hello'} 
why hello Jack 
--- greet() self=Person('Jill') args=() kwargs={} 
hello Jill 
--- greet() self=Person('Jill') args=('hi',) kwargs={} 
hi Jill 
--- greet() self=Person('Jill') args=() kwargs={'greeting': 'why hello'} 
why hello Jill 

원숭이 패치의 이점은 향후 모든 인격 인스턴스입니다.사람은 실제로 생성 된 프록시 객체의 인스턴스가됩니다. Monkey patching은 그것을 사용하기 전에 명심해야 할 이슈들로 구성되어 있습니다.