파이썬에서 변수에 목록이나 튜플이 있는지 테스트하는 가장 좋은 방법은 무엇입니까? (즉, 컬렉션)
가 isinstance()
여기에 제안 악? http://www.canonical.org/~kragen/isinstance/
업데이트 : 목록과 문자열을 구별하려는 가장 일반적인 이유는 무한한 중첩 트리 / 문자열 목록 목록의 데이터 구조 등이 있는데 재귀 알고리즘으로 탐색하고 필요합니다. "리프"노드에 도달했을 때 알 수 있습니다.
파이썬에서 변수에 목록이나 튜플이 있는지 테스트하는 가장 좋은 방법은 무엇입니까? (즉, 컬렉션)
가 isinstance()
여기에 제안 악? http://www.canonical.org/~kragen/isinstance/
업데이트 : 목록과 문자열을 구별하려는 가장 일반적인 이유는 무한한 중첩 트리 / 문자열 목록 목록의 데이터 구조 등이 있는데 재귀 알고리즘으로 탐색하고 필요합니다. "리프"노드에 도달했을 때 알 수 있습니다.
답변:
isinstance
필요한 경우 계속 사용 하십시오. 커스텀 시퀀스, 반복자 및 실제로 필요한 다른 것들을 배제하기 때문에 다소 악합니다. 그러나 누군가가 예를 들어 문자열을 전달하는 경우 때때로 다르게 행동해야합니다. 내 선호는 명시 적으로 확인 str
하거나 unicode
좋아하는 것입니다.
import types
isinstance(var, types.StringTypes)
NB 마 혼동하지 types.StringType
위해 types.StringTypes
. 후자는 통합 str
하고 unicode
반대한다.
types
모듈은 오히려 위를 사용하지 않는 게 좋을 그래서 만약 당신이 다른 방법에 대해 명시 적으로 확인할 수 있습니다, 단지 객체의 유형에 대해 직접 확인 찬성 쓸모 많은 것에 의해 간주 str
하고 unicode
다음과 같이 :
isinstance(var, (str, unicode)):
편집하다:
더 나은 방법은 다음과 같습니다.
isinstance(var, basestring)
편집 종료
이 중 하나를 마치면 정상적인 시퀀스를 얻는 것처럼 동작하여 비 시퀀스가 적절한 예외를 발생시킬 수 있습니다.
유형 검사에 대해 "악한"것은 특정 유형의 객체에 대해 다르게 행동하기를 원치 않는 것이 아니라, 예상치 못한 객체 유형으로 올바른 행동을 수행하지 못하도록 인위적으로 기능을 제한하는 것입니다. 유형 확인되지 않은 최종 폴 백이 있으면이 제한을 제거합니다. 너무 많은 유형 검사는 리팩토링을 원할 수도 있음을 나타내는 코드 냄새이지만 반드시 getgo에서 피해야한다는 것을 의미하지는 않습니다.
str
유형을 확인 해야하는 경우 types.StringType
별칭을 사용 하는 대신 직접 사용해야 합니다. 그러나 나는이 답변이 "컬렉션"에 관한 것이기 때문에 질문에 대답하지 않는다고 생각합니다. 확인할 수있는 abc
모듈이 아닌 새로운 파이썬을 사용하지 않는 한 isinstance
, 가능하다면 검사를 피하는 것이 좋습니다.
assert isinstance(u'abc', str) == False
. types
모듈을 사용하는 대신 유형을 직접 확인하는 것이 좋지만 types.StringTypes
그렇지 않은 작업은 str
수행 합니다. True for str
및 unicode
objects를 반환 합니다. 대안으로 이중 확인을 제공하기 위해 응답을 편집하겠습니다.
isinstance
악?" 그리고 나는 (1)의 악의가 아닌 사용이라는 반대의 예를 isinstance
들었습니다. 무언가는 list
또는 tuple
(즉, 문자열에서 명확하게하기 위해)입니다.
class Foo(str): pass
당신이 원하는 무엇입니까?
if type(x) is list:
print 'a list'
elif type(x) is tuple:
print 'a tuple'
else:
print 'neither a tuple or a list'
type([]) is list
리턴True
type(x) in [list,tuple]
더 짧습니다.
isinstance
중복되지 않는 한 사용 하는 데 아무런 문제가 없습니다. 변수가 목록 / 튜플 일뿐이라면 인터페이스를 문서화하고 그대로 사용하십시오. 그렇지 않으면 수표는 완벽하게 합리적입니다.
if isinstance(a, collections.Iterable):
# use as a container
else:
# not a container!
이 유형의 검사에는 표준 문자열 startswith / endswith 메소드 와 같은 유용한 유스 케이스 가 있습니다 (정확하지만 튜플인지 확인하기 위해 명시 적 검사를 사용하여 CPython에서 C로 구현되지만 여러 가지 방법이 있습니다) 링크 된 기사에서 언급 했듯이이 문제를 해결하려면).
명시 적 검사는 종종 컨테이너로 객체를 사용하고 예외를 처리하는 것보다 낫습니다. 이로 인해 코드가 부분적으로 또는 불필요하게 실행되는 모든 종류의 문제가 발생할 수 있습니다.
set
객체는, 반복 가능하다 당신은 분명히 그것에서 요소를 팝업 할 수 있지만, 동안 특정 알고리즘을위한 매우 위험한 일입니다 특정 순서를 보장하지 않는다는 것을 의미합니다. 요소의 순서가 중요 할 경우이 스 니펫을 사용하는 알고리즘이 다른 실행에서 다른 결과를 생성 할 수 있습니다!
인수가 시퀀스 여야하는 것으로 문서화하고 시퀀스로 사용하십시오. 유형을 확인하지 마십시오.
어때요 hasattr(a, "__iter__")
?
반환 된 객체가 생성기로 반복 될 수 있는지 알려줍니다. 기본적으로 튜플과 목록은 문자열 유형이 아니라 문자열 유형이 될 수 있습니다.
__iter__
.
__iter__
... 어떤 이유
파이썬 2.8에서 type(list) is list
반환 false
할 때이 끔찍한 방식으로 유형을 비교하는 것이 좋습니다.
if type(a) == type([]) :
print "variable a is a list"
(적어도 내 시스템에서는 Mac OS X Yosemite에서 아나콘다를 사용함)
type(list) is list
반환 False
때문 type(list)
입니다 type
하지 list
. type(list()) is list
또는 목록의 다른 인스턴스 와 함께 반환 True
됩니다.
파이썬은 "오리 타이핑 (Duck typing)"을 사용합니다. 즉, 오리와 같은 변수가 오리라면 오리 여야합니다. 귀하의 경우 반복 가능하거나 특정 색인에서 항목에 액세스하려고 할 수 있습니다. 당신은 이것을해야합니다 : 즉 블록 내부 for var:
또는 var[idx]
내부 에서 객체를 사용하십시오 try
. 예외가 발생하면 오리가 아닙니다 ...
var
아마도 문자열 예기치 않은 결과와 함께 문자열 반복이 발생한다는 것입니다.