Python 클래스 의 동적 수정 인 스 턴 스 방법
많은 친구 들 이 프로 그래 밍 을 할 때 이미 작 성 된 프로그램 행동 코드 를 수정 하고 싶 어 할 것 이 라 고 믿 습 니 다.가장 흔히 볼 수 있 는 방법 은 하위 클래스 를 통 해 부모 류 의 수 요 를 만족 시 키 지 못 하 는 방법 을 다시 쓰 는 것 입 니 다.예 를 들 어 아래 의 이 예.
class Dog:
def bark(self):
print 'Woof!'
class Husky(Dog):
def bark(self)
print 'Howl!'
우 리 는 상술 한 방식 으로 우리 가 쓴 코드 를 수정 할 수 있 지만,우 리 는 어떻게 제3자 코드 를 수정 해 야 합 니까?물론,우 리 는 스스로 하위 클래스 를 작성 하여 하위 클래스 의 실례 대상 을 호출 하여 수정 을 실현 할 수 있 지만,이렇게 하면 다른 일련의 문 제 를 도입 할 수 있다.그래서 우 리 는 우리 자신의 방법 으로 원래 의 대상 방법 을 교체 하 는 방법 을 생각해 야 한다.이것 이 바로 본 고 에서 다음 에 소개 하고 자 하 는'패 치'방식 이다.패 치
만약 우리 가 대상 을 새로 늘 리 거나 수정 하 는 방법 을 원한 다 면,가장 간단 한 방법 은 클래스 에 패 치 를 하 는 것 이다.위의 예 와 결합 하여,만약 우리 가 자신의 Dog 클래스 에 새로운 howl 방법 을 쓰 고 싶다 면,우 리 는 새로운 howl 함 수 를 정의 할 수 있 습 니 다.아래 코드 처럼 그것 을 우리 클래스 에 추가 할 수 있 습 니 다.
def newbark(self):
print 'Wrooof!'
def howl(self):
print 'Howl!'
# Replace an existing method
Dog.bark = newbark
# Add a new method
Dog.howl = howl
쉽 죠?하지만 여기 에는 우리 가 주의해 야 할 몇 가지 문제 가 있다.우선,수 정 된 클래스 의 모든 인 스 턴 스 방법 이 업데이트 되 기 때문에 업 데 이 트 된 방법 은 새로 만 든 대상 에 만 존재 하 는 것 이 아니 라 이전에 만 든 모든 대상 은 업데이트 후의 방법 을 가지 고 있 습 니 다.원래 의 방법 을 덮어 쓰 는 것 이 아니 라 새로 만 든 방법 만 있 습 니 다.둘째,당신 이 수정 하거나 새로 추가 한 방법 은 대상 과 연결 되 어야 하기 때문에 방법의 첫 번 째 매개 변 수 는 호출 된 대상 이 어야 합 니 다(여기 서 클래스 의 인 스 턴 스 self).클래스 인 스 턴 스 패 치
하나의 대상 도 이런 종류의 다른 실례 에 영향 을 주지 않 는 상황 에서 패 치 를 할 수 있다.그래도 팁 이 좀 있어 요!먼저 아래 의 이 예 를 보 여 주세요.
def herd(self, sheep):
self.run()
self.bark()
self.run()
border_collie = Dog()
border_collie.herd = herd
그리고 우 리 는 새로운 정 의 를 호출 하 는 방법 을 다시 시도 해 보 자.
border_collie.herd(sheep)
TypeError: herd() takes exactly 2 arguments (1 given)
The problem with the previous code is that the herd is not a bound method, just take a look at the following code:
print border_collie.herd
<function herd at 0xf9c5f0>
틀 렸 어!오 류 를 일 으 키 는 이 유 는 호출 된 대상 이 첫 번 째 매개 변수 로 우리 에 게 전 달 된 함수 가 아니 기 때문이다.물론 우 리 는 스스로 파 라 메 터 를 전달 할 수 있 지만 이런 교체 방법 은 효과 가 없다.이 문 제 를 해결 하 는 정확 한 방안 은 type 이 모듈 의 MethodType 함수 입 니 다.아래 의 예제 코드 를 볼 수 있 습 니 다.
import types
border_collie = Dog()
border_collie.herd = types.MethodType(herd, border_collie)
print border_collie.herd
<bound method ?.herd of <__main__.Dog instance at 0x23c9518>>
border_collie.herd(sheep)
지금 우리 의 방법 은 이미 실례 와 연결 되 어 큰 성 과 를 거 두 었 습 니 다!총결산
실행 중 에 교체 하거나 추가 하 는 방법 은 매우 유용 하 다.예 를 들 어 유닛 테스트 에서 외부 서비스 와 통신 을 담당 하 는 함수 가 있 으 면 교체 하고 테스트 하기에 편리 하 다.이 기술 은 자주 사용 할 뿐만 아니 라 코드 를 수정 하기 전에 코드 의 유지 가능성 을 유지 할 수 있 는 매우 중요 한 기술 입 니 다.
읽 어 주 셔 서 감사합니다. 여러분 에 게 도움 이 되 기 를 바 랍 니 다.본 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!