때때로 컨테이너 유형의 경우 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
하나는 bytes
그 str
이며, 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
대 어딘가에 끈 같은 용기에 대한 디자인 토론이 있습니까?
1. 내가 아는 한 멀지 않습니다. 2. * "문자열과 같은 컨테이너"* *는 단일 문자 문자열/바이트의 시퀀스입니다 (ByteString은 Sequence를 상속받습니다). * "vs"*는 실제로 만들지 않습니다. 감각. 대부분의 경우 문자열은 시퀀스를 취하는 함수 나 메서드에 대한 완벽한 유효한 인수로 간주되므로 그렇지 않은 경우 명시 적이어야합니다. 의견을 주신 덕분에 @jonrsharpe – jonrsharpe
! 나는 상황에 따라 "* vs *"가 적절할 수 있다고 주장한다. 종종 문자열 (바이트 등)을 단일 원자 데이터 포인트로 생각하고 있으며 문자열과 같은 항목의 목록과 같은 컨테이너를 다루고 있는지, 아니면 단일 문자열과 같은 것을 처리하고 있는지 알고 싶습니다. 목. 이것은 하나의 장소입니다. 예를 들어 중첩 된 사전을 병합하기 위해 재귀 함수를 사용하는 것입니다. 예를 들어 항목 유형에 전달하려는 재귀 함수 내부에서. – DGrady