2017-04-19 1 views
6

때때로 컨테이너 유형의 경우 Python은 Abstract Base Classes (원래는 PEP 3119으로 제안되었습니다) 특히 사용자 정의를 통해 일반화 된 코드를 작성하기가 쉽습니다 유형. 예를 들어, 몇 번 나를 넘어 년대 '개는'의Python 3의 표준 라이브러리를 사용하여 문자열과 유사하지 않은 시퀀스를 테스트하는 방법

from collections.abc import Sequence, Set 

if isinstance(x, Sequence): 
    # Handle lists, tuples, or custom objects that behave like lists 
elif isinstance(x, Set): 
    # Handle anything that behaves like a set 

하나는 bytesstr이며, bytearray 모두 더 분명 목록과 같은 객체에 추가하여, Sequence의 간주됩니다 :

from collections.abc import ByteString, Sequence 

s = 'hello' 
b = b'hello' 
ba = bytearray(b'hello') 
lst = [0, 1, 2] 
t = (0, 1, 2) 

islistlike = lambda x: isinstance(x, Sequence) 

list(map(islistlike, [s, b, ba, lst, t])) # -> [True, True, True, True, True] 

일반적으로이 세 유형은 문자 (또는 바이트)의 목록 또는 튜플처럼 작동합니다. 그러나, 물어 꽤 일반적인 사용 사례처럼 보인다이 개체 x 모두 목록과 같은 아닌 문자열처럼? 수정은 간단하다 :

islistlike = lambda x: isinstance(x, Sequence) and not isinstance(x, (str, ByteString)) 

list(map(islistlike, [s, b, ba, lst, t])) # -> [False, False, False, True, True] 

하지만 내가 표준 라이브러리에서 뭔가를 누락 궁금 공통 충분한 패턴 것 같은이 보인다.

  • islistlike = lambda x: isinstance(x, abc) 위의 마지막 예제처럼 행동 것이다 있도록 파이썬의 표준 라이브러리에있는 abc이 있습니까?
  • Sequence 대 어딘가에 끈 같은 용기에 대한 디자인 토론이 있습니까?
+0

1. 내가 아는 한 멀지 않습니다. 2. * "문자열과 같은 컨테이너"* *는 단일 문자 문자열/바이트의 시퀀스입니다 (ByteString은 Sequence를 상속받습니다). * "vs"*는 실제로 만들지 않습니다. 감각. 대부분의 경우 문자열은 시퀀스를 취하는 함수 나 메서드에 대한 완벽한 유효한 인수로 간주되므로 그렇지 않은 경우 명시 적이어야합니다. 의견을 주신 덕분에 @jonrsharpe – jonrsharpe

+0

! 나는 상황에 따라 "* vs *"가 적절할 수 있다고 주장한다. 종종 문자열 (바이트 등)을 단일 원자 데이터 포인트로 생각하고 있으며 문자열과 같은 항목의 목록과 같은 컨테이너를 다루고 있는지, 아니면 단일 문자열과 같은 것을 처리하고 있는지 알고 싶습니다. 목. 이것은 하나의 장소입니다. 예를 들어 중첩 된 사전을 병합하기 위해 재귀 함수를 사용하는 것입니다. 예를 들어 항목 유형에 전달하려는 재귀 함수 내부에서. – DGrady

답변

1

아니, 쉽게 다른 시퀀스 유형에 대 -like str 사이 bytes 시퀀스를 구분하는 표준 라이브러리에서 아무 것도 없다 (I는 표준 라이브러리의 문서 또는 PEP 3119.이 관련 아무것도 발견하지 않았습니다). 이것이 코드베이스에서 일반적이라면 직접 롤업 할 수 있습니다.

관련 문제