답변:
아니요, 그것은 그런 것들과 다릅니다. 단순히 런타임에 속성을 동적으로 대체하는 것입니다.
예를 들어, 메소드가있는 클래스를 고려하십시오 get_data
. 이 메소드는 외부 조회 (예 : 데이터베이스 또는 웹 API)를 수행하고 클래스의 다양한 기타 메소드가이를 호출합니다. 그러나 단위 테스트에서는 외부 데이터 소스에 의존하고 싶지 않으므로 get_data
고정 된 데이터를 반환하는 스텁으로 메서드 를 동적으로 바꿉니다.
파이썬 클래스는 변경 가능하고 메소드는 클래스의 속성 일 뿐이므로 원하는만큼이 작업을 수행 할 수 있으며 실제로 모듈에서 클래스와 함수를 같은 방식으로 대체 할 수도 있습니다.
그러나 주석가가 지적했듯이 원숭이 패치를 할 때주의하십시오.
테스트 로직 이외의 다른 항목 get_data
도 호출하면 원본보다 원숭이 패치 교체를 호출합니다. 좋거나 나쁠 수 있습니다. 조심하세요.
get_data
대체 할 때 까지 함수를 가리키는 일부 변수 또는 속성이 존재하는 경우이 별명은 의미를 변경하지 않으며 원래를 계속 가리 킵니다 get_data
. (왜 파이썬은 get_data
클래스 의 이름 을 다른 함수 객체에 리 바인딩합니다. 다른 이름 바인딩은 전혀 영향을받지 않습니다.)
pointing to the original get_data function
합니까? 누군가가 그 기능을 변경하면 변수가 기존 변수를 계속 가리키면 변수 안에 함수를 저장한다는 의미입니까?
get_data
하면 이름 get_data
을 모의 함수로 리 바인드합니다 . 프로그램의 다른 곳에서 다른 이름이 function-formerly-known-as-에 바인딩 된 get_data
경우 해당 다른 이름에 대해서는 아무 것도 변경되지 않습니다.
MonkeyPatch는 런타임에 (일반적으로 시작시) 다른 코드를 확장하거나 수정하는 Python 코드 조각입니다.
간단한 예는 다음과 같습니다.
from SomeOtherProduct.SomeModule import SomeClass
def speak(self):
return "ook ook eee eee eee!"
SomeClass.speak = speak
출처 : Zope 위키의 MonkeyPatch 페이지.
원숭이 패치 란 무엇입니까?
간단히 말해서, 원숭이 패치는 프로그램이 실행되는 동안 모듈이나 클래스를 변경합니다.
Pandas 문서에는 원숭이 패치의 예가 있습니다.
import pandas as pd
def just_foo_cols(self):
"""Get a list of column names containing the string 'foo'
"""
return [x for x in self.columns if 'foo' in x]
pd.DataFrame.just_foo_cols = just_foo_cols # monkey-patch the DataFrame class
df = pd.DataFrame([list(range(4))], columns=["A","foo","foozball","bar"])
df.just_foo_cols()
del pd.DataFrame.just_foo_cols # you can also remove the new method
이를 해결하기 위해 먼저 모듈을 가져옵니다.
import pandas as pd
다음으로 클래스 정의의 범위를 벗어나는 바인딩되지 않은 상태로 존재하는 메서드 정의를 만듭니다 (함수와 바인딩되지 않은 메서드는 구별이 무의미하기 때문에 Python 3은 바인딩되지 않은 메서드를 사용하지 않습니다).
def just_foo_cols(self):
"""Get a list of column names containing the string 'foo'
"""
return [x for x in self.columns if 'foo' in x]
다음으로 사용하려는 클래스에 해당 메소드를 연결합니다.
pd.DataFrame.just_foo_cols = just_foo_cols # monkey-patch the DataFrame class
그런 다음 클래스의 인스턴스에서 메소드를 사용하고 완료되면 메소드를 삭제할 수 있습니다.
df = pd.DataFrame([list(range(4))], columns=["A","foo","foozball","bar"])
df.just_foo_cols()
del pd.DataFrame.just_foo_cols # you can also remove the new method
이름 변환 (이중 밑줄이 붙은 접두어로 이름을 변경하고 권장하지 않는 속성)을 사용하는 경우이 작업을 수행하면 수동으로 이름을 바꿔야합니다. 이름 맹 글링을 권장하지 않기 때문에 여기서는 설명하지 않습니다.
예를 들어 테스트에서이 지식을 어떻게 사용할 수 있습니까?
이러한 경우에 올바른 동작을 보장하기 위해 외부 데이터 소스에 대한 데이터 검색 호출을 시뮬레이션해야 오류가 발생한다고 가정하십시오. 이 동작을 보장하기 위해 데이터 구조를 원숭이 패치 할 수 있습니다. (따라서 Daniel Roseman이 제안한 것과 비슷한 메소드 이름을 사용하십시오.)
import datasource
def get_data(self):
'''monkey patch datasource.Structure with this to simulate error'''
raise datasource.DataRetrievalError
datasource.Structure.get_data = get_data
오류를 발생시키는이 방법에 의존하는 동작을 테스트 할 때 올바르게 구현하면 테스트 결과에 해당 동작이 나타납니다.
위의 작업을 수행하면 Structure
프로세스 수명 동안 객체 가 변경 되므로 단위 테스트에서 설정 및 분해를 사용하여 수행하지 않도록하십시오.
def setUp(self):
# retain a pointer to the actual real method:
self.real_get_data = datasource.Structure.get_data
# monkey patch it:
datasource.Structure.get_data = get_data
def tearDown(self):
# give the real method back to the Structure object:
datasource.Structure.get_data = self.real_get_data
(위의 내용은 훌륭하지만 mock
코드를 패치 하기 위해 라이브러리 를 사용하는 것이 더 좋습니다 . mock
'의 patch
데코레이터는 위의 작업보다 오류가 적기 때문에 더 많은 코드 줄이 필요하므로 오류가 발생할 가능성이 더 큽니다. 코드를 아직 검토하지 않았지만 mock
비슷한 방식으로 원숭이 패치를 사용한다고 상상합니다.)
첫째 : 원숭이 패치는 사악한 해킹입니다 (제 생각에는).
모듈 또는 클래스 레벨의 메소드를 사용자 정의 구현으로 바꾸는 데 종종 사용됩니다.
가장 일반적인 사용 사례는 원래 코드를 바꿀 수 없을 때 모듈이나 클래스의 버그에 대한 해결 방법을 추가하는 것입니다. 이 경우 원숭이 패치를 통해 "잘못된"코드를 자체 모듈 / 패키지 내부의 구현으로 바꿉니다.
원숭이 패치는 동적 언어로만 수행 할 수 있으며, 그 중 파이썬이 좋은 예입니다. 객체 정의를 업데이트하는 대신 런타임에 메소드를 변경하는 것이 한 예입니다. 마찬가지로 런타임에 속성 (메소드 또는 변수)을 추가하는 것은 원숭이 패치로 간주됩니다. 이것들은 종종 소스가없는 모듈로 작업 할 때 수행되므로 객체 정의를 쉽게 변경할 수 없습니다.
이것은 객체의 정의가 실제로 어떻게 동작하는지 완전히 또는 정확하게 설명하지 않기 때문에 나쁜 것으로 간주됩니다.
원숭이 패치 란 무엇입니까? 원숭이 패치는 런타임에 코드 조각의 동작을 동적으로 업데이트하는 데 사용되는 기술입니다.
원숭이 패치를 사용하는 이유는 무엇입니까? 실제로 소스 코드를 수정하지 않고도 런타임에 라이브러리, 모듈, 클래스 또는 메소드의 동작을 수정하거나 확장 할 수 있습니다.
결론 Monkey patching은 멋진 기술이며 이제 파이썬에서 그 방법을 배웠습니다. 그러나 우리가 논의했듯이, 그것은 그 자체의 단점이 있으며 신중하게 사용해야합니다.
자세한 내용은 다음을 참조하십시오 [1] : https://medium.com/@nagillavenkatesh1234/monkey-patching-in-python-explained-with-examples-25eed0aea505
Monkey patching is a technique to add, modify, or suppress the default behavior of a piece of code at runtime without changing its original source code.