최근 Hacker Newsletter 호에는 Python의 데코레이터에 관한 this very useful article이 링크되었습니다. 나는 기사를 좋아하고 나는 대부분의 데코레이터 예제를 이해한다고 생각한다. 그러나, 비 장식의 메모이 제이션 예제에서, 나는 코드에 의해 매우 혼란 스러워요 :Python memoization 코드 스 니펫을 이해하려고 시도했습니다
def memoize(fn):
stored_results = {}
def memoized(*args):
try:
# try to get the cached result
return stored_results[args]
except KeyError:
# nothing was cached for those args. let's fix that.
result = stored_results[args] = fn(*args)
return result
return memoized
나는이 기능이 추가 된 가져옵니다 지속 사전 stored_results
을 만들 것입니다 방법에 대한 혼란 스러워요. 그것을 다시 읽은 후, 그것을 내 편집자에게 복사/붙여 넣기하고 그것을 가지고 노는 것과 도움을 얻기 위해 온라인으로 찾는 것, 나는 여전히 구문이 무엇인지 이해하지 못합니다. stored_results[args] = fn(*args)
.
(1)이 기사에서는 위의 코드가 함수를 반환하지만 이제는 새로운 인수로 실행하기 전에 사전을 먼저 검색 할 것이라고 제안합니다. 어떻게 될까요? stored_results
은 memoize
에 국한되는 이유는 무엇입니까? memoized
이 반송되면 왜 파괴되지 않습니까?
(2) *args
으로 전달되는 인수를 설명하는 다른 질문이나 웹 리소스에 대한 링크도 도움이 될 것입니다. *args
이 목록 인 경우 인수를 사용하면 왜 stored_results[args]
구문을 사용할 수 있습니까? 목록에서 사전 색인을 생성 할 때 일반적으로 해시 가능하지 않은 오류가 발생하는 이유는 무엇입니까?
의견을 보내 주셔서 감사합니다. 우리가 목록에 인덱스 사전을하려고 할 때 보통이 아닌 해쉬 오류 구문 stored_results[args]
을 사용할 수 있습니다 왜 *args
하면
그래서'fn (* args)'는'args'의 원소로 된 튜플을'fn()'함수로 푸시합니다. 이것은'stored_results'가 * 전체 튜플 *에 의해 인덱스되는 엔트리를 가지고 있다는 것을 의미합니까? 링크의 예에서는 피보나치 함수를 사용합니다. 그래서 함수를 하나의 정수 인자, 즉'6'라고 부르면 사전은'{(6) : 8, ...} '과 같은 엔트리를 갖도록 확장 될 것입니까? 그렇다면 하나의 질문을 해결한다 : 그것은'args '로 가득 찬 전체 튜플이 하나의 암기 된 키로 사용된다고 가정한다. 여전히'stored_results'가 새로운 함수에 대한 여러 호출에서 지속되는 이유가 궁금합니다. – ely
정의 된 내부 memoized 물건은 프록시에 의해서'stored_results'에 대해서만 알고있는 것처럼 보입니다. 파이썬은 내부적으로'memoized'의 정의가 그것을 가리 키기 때문에이 객체를 암시 적으로 유지합니까? – ely
@EMS 예, memoized 함수는이 객체에 대한 참조를 가지고 있으므로 pythong은이를 가비지 수집하지 않습니다. "자유 변수"를 가진 이런 종류의 함수는 [closure] (http://en.wikipedia.org/wiki/Closure_ (computer_science))라고합니다. – tobyodavies