code

collections.ChainMap의 목적은 무엇입니까?

codestyles 2020. 12. 8. 08:06
반응형

collections.ChainMap의 목적은 무엇입니까?


Python 3.3에서는 모듈에 ChainMap클래스가 추가되었습니다 collections.

ChainMap 클래스는 여러 매핑을 빠르게 연결하여 단일 단위로 처리 할 수 ​​있도록 제공됩니다. 새 사전을 만들고 여러 개의 update () 호출을 실행하는 것보다 훨씬 빠릅니다.

예:

>>> from collections import ChainMap
>>> x = {'a': 1, 'b': 2}
>>> y = {'b': 10, 'c': 11}
>>> z = ChainMap(y, x)
>>> for k, v in z.items():
        print(k, v)
a 1
c 11
b 10

그것은에 의해 좌우 된 이 문제 에 의해 만들어진 대중 이 하나 (더 PEP생성되지 않았다).

내가 이해하는 한, 여분의 사전을 가지고 update()s로 유지하는 것의 대안 입니다.

질문은 다음과 같습니다.

  • 어떤 사용 사례를 ChainMap다루나요?
  • 실제 사례가 ChainMap있습니까?
  • python3으로 전환 된 타사 라이브러리에서 사용됩니까?

보너스 질문 : Python2.x에서 사용할 수있는 방법이 있습니까?


Transforming Code into Beautiful, Idiomatic PythonRaymond Hettinger의 PyCon 토크 에서 그것에 대해 들었고 내 툴킷에 추가하고 싶지만 언제 사용 해야하는지 이해가 부족합니다.


나는 @ b4hand의 예제를 좋아하고, 실제로 그가 언급 한 두 가지 목적으로 과거 ChainMap과 유사한 구조 (ChainMap 자체는 아님)를 사용했습니다. 다층 구성 재정의 및 가변 스택 / 범위 에뮬레이션입니다.

ChainMapdict-update 루프를 사용하여 "최종"버전 만 저장하는 것과 비교하여 의 다른 두 가지 동기 / 장점 / 차이점을 지적하고 싶습니다 .

  1. 추가 정보 : ChainMap 구조는 "계층화"되어 있기 때문에 다음과 같은 질문에 대한 대답을 지원합니다. "기본값"값을 얻었습니까, 아니면 재정의 된 값을 얻습니까? 원래 ( "기본값") 값은 무엇입니까? 어떤 수준에서 값이 재정의 되었습니까 (@ b4hand의 구성 예 : user-config 또는 command-line-overrides 차용)? 간단한 사전을 사용하면 이러한 질문에 답하는 데 필요한 정보가 이미 손실되었습니다.

  2. 속도 절충 : 체인 맵 테이크 와 각 룩업 최악의 경우 [*]를 구성하고 업데이트 루프 테이크 와 각 룩업을 사용하여 딕셔너리를 구성하면서 각각에 N레이어와 최대 M가 있다고 가정합니다 . 즉, 자주 구성하고 매번 몇 번의 조회 만 수행하거나 큰 경우 ChainMap의 lazy-construction 접근 방식이 유리하게 작동합니다.O(N)O(N)O(NM)O(1)M

[*] (2)의 분석은 dict-access가 O(1)실제로 O(1)평균이고 O(M)최악의 경우라고 가정합니다. 여기에서 자세한 내용을 참조 하십시오 .


ChainMap명령 줄 옵션, 사용자 구성 파일 및 시스템 구성 파일과 같은 여러 구성 범위가있는 구성 개체에 사용 하는 것을 볼 수 있습니다 . 조회는 생성자 인수의 순서에 따라 정렬되므로 더 낮은 범위에서 설정을 재정의 할 수 있습니다. 개인적으로 사용하거나 사용한 적이 없지만 ChainMap표준 라이브러리에 상당히 최근에 추가 된 것이므로 놀라운 일이 아닙니다.

어휘 범위를 직접 구현하려는 경우 변수 바인딩을 푸시하고 팝하는 스택 프레임을 에뮬레이션하는데도 유용 할 수 있습니다.

ChainMap표준 라이브러리 문서는 타사 라이브러리의 유사한 구현에 대한 몇 가지 예제와 링크를 제공합니다. 특히 Django의 Context 클래스 와 Enthought의 MultiContext 클래스 이름을 지정 합니다.


나는 이것에 균열을 가질 것이다.

Chainmap은 매우 일종의 추상화처럼 보입니다. 매우 특수한 종류의 문제에 대한 좋은 해결책입니다. 이 사용 사례를 제안합니다.

당신이 가지고 있다면:

  1. 다중 매핑 (예 : dicts)
  2. 이러한 매핑의 일부 키 중복 (동일한 키가 여러 매핑에 나타날 수 있지만 모든 키가 모든 매핑에 나타나는 경우는 아님)
  3. 주어진 키에 대한 모든 매핑에 대한 전체 순서가있는 "가장 높은 우선 순위"매핑의 키 값에 액세스하려는 소비 애플리케이션 (즉, 매핑의 우선 순위가 동일 할 수 있지만 해당 매핑 내에 키 중복이 없습니다.) (Python 애플리케이션에서 패키지는 동일한 디렉토리 (동일한 우선 순위)에있을 수 있지만 다른 이름을 가져야하므로 정의에 따라 해당 디렉토리의 기호 이름은 중복 될 수 없습니다.)
  4. 소비 애플리케이션은 키 값을 변경할 필요가 없습니다.
  5. 동시에 매핑은 독립적 인 정체성을 유지해야하며 외부 힘에 의해 비동기 적으로 변경 될 수 있습니다.
  6. 매핑은 충분히 크고, 액세스하기에 충분히 비싸거나, 애플리케이션 액세스간에 충분히 자주 변경되므로, 앱에서 필요할 때마다 프로젝션을 계산하는 비용 (3)은 애플리케이션의 중요한 성능 문제입니다.

그런 다음 체인 맵을 사용하여 매핑 컬렉션에 대한보기를 만드는 것을 고려할 수 있습니다.

그러나 이것은 모두 사후 정당화입니다. 파이썬 사람들은 문제가 있었고, 코드 맥락에서 좋은 해결책을 내놓은 다음, 우리가 선택하면 사용할 수 있도록 해결책을 추상화하기 위해 추가 작업을했습니다. 그들에게 더 많은 힘. 그러나 그것이 당신의 문제에 적합한 지 여부는 당신이 결정해야합니다.


불완전하게 대답하려면 :

보너스 질문 : Python2.x에서 사용할 수있는 방법이 있습니까?

from ConfigParser import _Chainmap as ChainMap

그러나 이것은 실제가 아니며 다음에서 ChainMap상속되고 DictMixin정의합니다.

__init__(self, *maps)
__getitem__(self, key)
keys(self)

# And from DictMixin:
__iter__(self)
has_key(self, key)
__contains__(self, key)
iteritems(self)
iterkeys(self)
itervalues(self)
values(self)
items(self)
clear(self)
setdefault(self, key, default=None)
pop(self, key, *args)
popitem(self)
update(self, other=None, **kwargs)
get(self, key, default=None)
__repr__(self)
__cmp__(self, other)
__len__(self)

Its implementation also doesn't seem particularly efficient.

참고URL : https://stackoverflow.com/questions/23392976/what-is-the-purpose-of-collections-chainmap

반응형