파이썬에서 객체가 반복 가능한지 어떻게 결정합니까?
같은 방법이 isiterable
있습니까? 지금까지 찾은 유일한 해결책은 전화하는 것입니다.
hasattr(myObj, '__iter__')
그러나 이것이 얼마나 어리석은 지 잘 모르겠습니다.
__iter__
시퀀스 유형에 대한 작업을 확인 하지만 예를 들어 Python 2의 문자열 에서는 실패합니다 . 나도 정답을 알고 싶습니다. 그때까지 한 가지 가능성이 있습니다 (문자열에서도 작동합니다).try: some_object_iterator = iter(some_object) except TypeError as te: print some_object, 'is not iterable'
iter
위한 내장 검사__iter__
방법 또는 스트링 인 경우__getitem__
방법.또 다른 일반적인 비단뱀 접근 방식은 반복 가능하다고 가정하고 주어진 객체에서 작동하지 않으면 정상적으로 실패하는 것입니다. Python 용어집 :
그 방법 또는 속성 서명 검사를 통해서가 아니라 어떤 종류의 객체 ( "그것이 보이는 경우에 명시 적 관계에 의해 객체의 유형을 결정하는 파이썬 프로그래밍 스타일 오리 와 같은 꽥꽥 오리 , 그것은해야합니다 오리 강조 인터페이스에 의해.") 특정 유형이 아닌 잘 설계된 코드는 다형성 대체를 허용하여 유연성을 향상시킵니다. 덕 타이핑은 type () 또는 isinstance ()를 사용하는 테스트를 피합니다. 대신, 일반적으로 EAFP (권한보다 용서하기 쉬움) 스타일의 프로그래밍을 사용합니다.
...
try: _ = (e for e in my_object) except TypeError: print my_object, 'is not iterable'
이
collections
모듈은 몇 가지 추상 기본 클래스를 제공하여 클래스 나 인스턴스가 특정 기능을 제공하는지 물어볼 수 있습니다. 예를 들면 다음과 같습니다.from collections.abc import Iterable if isinstance(e, Iterable): # e is iterable
그러나를 통해 반복 가능한 클래스는 확인하지 않습니다
__getitem__
.
오리 타이핑
try:
iterator = iter(theElement)
except TypeError:
# not iterable
else:
# iterable
# for obj in iterator:
# pass
유형 검사
추상 기본 클래스를 사용합니다 . 최소한 Python 2.6이 필요하며 새로운 스타일의 클래스에서만 작동합니다.
from collections.abc import Iterable # import directly from collections for Python < 3.3
if isinstance(theElement, Iterable):
# iterable
else:
# not iterable
그러나 문서에iter()
설명 된 대로 좀 더 신뢰할 수 있습니다 .
검사
isinstance(obj, Iterable)
는 Iterable로 등록되었거나__iter__()
메소드 가있는 클래스를 감지하지만 메소드로 반복되는 클래스는 감지하지 않습니다__getitem__()
. 객체가 반복 가능한지 확인하는 유일한 방법은를 호출하는 것iter(obj)
입니다.
나는 조금의 상호 작용에 더 많은 빛 비트 창고 싶습니다 iter
, __iter__
그리고 __getitem__
어떤 커튼 뒤에 발생합니다. 그 지식으로 무장하면 왜 최선을 다하는 것인지 이해할 수있을 것입니다.
try:
iter(maybe_iterable)
print('iteration will probably work')
except TypeError:
print('not iterable')
먼저 사실을 나열한 다음 for
파이썬에서 루프 를 사용할 때 어떤 일이 발생하는지에 대한 빠른 알림을 받은 다음 사실을 설명하기위한 토론이 이어집니다.
사리
당신은 어떤 개체에서 반복자를 얻을 수 있습니다
o
호출하여iter(o)
다음 조건 중 하나 이상이 사실이 보유하고있는 경우
)를o
이__iter__
반복자 객체를 반환하는 방법을. 반복자는__iter__
및__next__
(Python 2 :)next
메서드 가있는 모든 개체입니다 .
b)o
갖는__getitem__
방법.Iterable
또는 의 인스턴스를Sequence
확인하거나 속성을 확인하는__iter__
것만으로는 충분하지 않습니다.객체의 경우
o
구현은__getitem__
아니지만__iter__
,iter(o)
시도로부터 아이템을 취득하는 것을 반복자 구성합니다o
인덱스 0에서 시작하는 정수 인덱스를 반복자는 잡을 것IndexError
제기입니다 (하지만 다른 오류를) 다음 제기StopIteration
자체를.가장 일반적인 의미에서에서 반환 된 반복기
iter
가 정상 인지 확인하는 것 외에는 시도 할 방법이 없습니다.객체가를
o
구현__iter__
하면iter
함수는에서 반환 된 객체__iter__
가 반복자 인지 확인 합니다. 객체가를 구현하는 경우에는 온 전성 검사가 없습니다__getitem__
.__iter__
승리합니다. 객체의 경우o
구현 모두__iter__
하고__getitem__
,iter(o)
호출합니다__iter__
.자신의 객체를 반복 가능하게 만들려면 항상 추상 기본 클래스
Iterable
또는 하위 클래스 중 하나에서 상속하십시오.__iter__
메서드 를 구현해야합니다. 그렇지 않으면의 경우와 같이 제공됩니다Sequence
.
for
루프
따라하기 위해서는 for
Python 에서 루프 를 사용할 때 어떤 일이 발생하는지 이해해야 합니다. 이미 알고있는 경우 다음 섹션으로 바로 건너 뛰어도됩니다.
for item in o
일부 반복 가능한 객체에 사용할 때 o
Python iter(o)
은 반복기 객체를 반환 값으로 호출 하고 기대합니다. 반복자는 __next__
(또는 next
Python 2에서) 메서드와 메서드 를 구현하는 모든 객체입니다 __iter__
.
관례에 따라 __iter__
반복자 의 메서드는 객체 자체를 반환해야합니다 (예 :) return self
. 그런 다음 Python next
은가 발생할 때까지 반복기 를 호출 합니다 StopIteration
. 이 모든 작업은 암시 적으로 발생하지만 다음 데모에서는이를 볼 수 있습니다.
import random
class DemoIterable(object):
def __iter__(self):
print('__iter__ called')
return DemoIterator()
class DemoIterator(object):
def __iter__(self):
return self
def __next__(self):
print('__next__ called')
r = random.randint(1, 10)
if r == 5:
print('raising StopIteration')
raise StopIteration
return r
반복 DemoIterable
:
>>> di = DemoIterable()
>>> for x in di:
... print(x)
...
__iter__ called
__next__ called
9
__next__ called
8
__next__ called
10
__next__ called
3
__next__ called
10
__next__ called
raising StopIteration
토론 및 삽화
포인트 1과 2에서 : 반복기 및 신뢰할 수없는 검사 얻기
다음 클래스를 고려하십시오.
class BasicIterable(object):
def __getitem__(self, item):
if item == 3:
raise IndexError
return item
을 구현 하기 때문에 iter
의 인스턴스를 사용하여 호출 BasicIterable
하면 문제없이 반복기가 반환됩니다 .BasicIterable
__getitem__
>>> b = BasicIterable()
>>> iter(b)
<iterator object at 0x7f1ab216e320>
그러나 속성이 없으며 or 의 인스턴스로 간주 b
되지 않는다는 점에 유의 해야합니다 .__iter__
Iterable
Sequence
>>> from collections import Iterable, Sequence
>>> hasattr(b, '__iter__')
False
>>> isinstance(b, Iterable)
False
>>> isinstance(b, Sequence)
False
이것이 Luciano Ramalho의 Fluent Python 이 객체가 반복 가능한지 확인하는 가장 정확한 방법으로 iter
잠재력 TypeError
을 호출 하고 처리하도록 권장하는 이유 입니다. 책에서 직접 인용 :
Python 3.4에서 객체
x
가 반복 가능한지 확인하는 가장 정확한 방법 은 그렇지 않은 경우 예외 를 호출iter(x)
하고 처리하는TypeError
것입니다. ABC는 그렇지 않은 반면 레거시 방법 도 고려isinstance(x, abc.Iterable)
하기 때문에를 사용하는 것보다 더 정확 합니다.iter(x)
__getitem__
Iterable
요점 3 :을 제공 __getitem__
하지만 제공 하지 않는 객체에 대한 반복__iter__
BasicIterable
예상대로 작업 인스턴스에 대해 반복 : Python은 0부터 시작하여 색인별로 항목을 가져 오려고 시도하는 반복기를 생성합니다 IndexError
. 데모 개체의 __getitem__
방법은 단순히 반환 item
에 인수로 제공 한을 __getitem__(self, item)
반복자에 의해 반환에 의해 iter
.
>>> b = BasicIterable()
>>> it = iter(b)
>>> next(it)
0
>>> next(it)
1
>>> next(it)
2
>>> next(it)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
이터레이터 StopIteration
는 다음 항목을 반환 할 수 없을 때 IndexError
발생하고 발생 item == 3
하는는 내부적으로 처리됩니다. 이상 반복하는 이유입니다 BasicIterable
A를 for
예상대로 루프 작동 :
>>> for x in b:
... print(x)
...
0
1
2
이터레이터 iter
가 인덱스로 항목에 액세스하려고 시도 하는 방식에 대한 개념을 설명하기위한 또 다른 예가 있습니다. WrappedDict
에서 상속하지 않으므로 dict
인스턴스에 __iter__
메서드 가 없습니다 .
class WrappedDict(object): # note: no inheritance from dict!
def __init__(self, dic):
self._dict = dic
def __getitem__(self, item):
try:
return self._dict[item] # delegate to dict.__getitem__
except KeyError:
raise IndexError
__getitem__
에 dict.__getitem__
대한 호출 은 대괄호 표기법이 단순히 속기 인 위임됩니다 .
>>> w = WrappedDict({-1: 'not printed',
... 0: 'hi', 1: 'StackOverflow', 2: '!',
... 4: 'not printed',
... 'x': 'not printed'})
>>> for x in w:
... print(x)
...
hi
StackOverflow
!
지점 4와 5에서 : 다음 iter
을 호출 할 때 반복자를 확인합니다__iter__
.
때 iter(o)
객체에 대해 호출 o
, iter
의 반환 값이 있는지 확인합니다 __iter__
방법이 존재하는 경우, 반복자입니다. 이는 반환 된 객체가 __next__
(또는 next
Python 2에서) 및 __iter__
. iter
을 (를) 제공하는 객체에 대한 온 전성 검사를 수행 할 수 없습니다. 이는 객체 __getitem__
의 항목이 정수 인덱스로 액세스 할 수 있는지 여부를 확인할 방법이 없기 때문입니다.
class FailIterIterable(object):
def __iter__(self):
return object() # not an iterator
class FailGetitemIterable(object):
def __getitem__(self, item):
raise Exception
FailIterIterable
인스턴스 에서 반복기를 생성 하면 즉시 실패하고 반복기를 생성 FailGetItemIterable
하면 성공하지만 .NET에 대한 첫 번째 호출에서 예외가 발생합니다 __next__
.
>>> fii = FailIterIterable()
>>> iter(fii)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: iter() returned non-iterator of type 'object'
>>>
>>> fgi = FailGetitemIterable()
>>> it = iter(fgi)
>>> next(it)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/path/iterdemo.py", line 42, in __getitem__
raise Exception
Exception
포인트 6 : __iter__
승리
이것은 간단합니다. 객체가 구현하는 경우 __iter__
와 __getitem__
, iter
호출합니다 __iter__
. 다음 클래스를 고려하십시오
class IterWinsDemo(object):
def __iter__(self):
return iter(['__iter__', 'wins'])
def __getitem__(self, item):
return ['__getitem__', 'wins'][item]
인스턴스를 반복 할 때 출력 :
>>> iwd = IterWinsDemo()
>>> for x in iwd:
... print(x)
...
__iter__
wins
요점 7 : 반복 가능한 클래스는 구현해야합니다. __iter__
왜 대부분의 내장 시퀀스 가 충분할 때 메소드를 list
구현 하는지 스스로 물어볼 수 있습니다 .__iter__
__getitem__
class WrappedList(object): # note: no inheritance from list!
def __init__(self, lst):
self._list = lst
def __getitem__(self, item):
return self._list[item]
결국, 반복 대표 호출 할 수있는 위 클래스의 인스턴스 이상 __getitem__
에 list.__getitem__
(대괄호 표기법을 사용하여) 잘 작동합니다 :
>>> wl = WrappedList(['A', 'B', 'C'])
>>> for x in wl:
... print(x)
...
A
B
C
커스텀 iterable이 구현해야하는 이유 __iter__
는 다음과 같습니다.
- 를 구현
__iter__
하면 인스턴스가 반복 가능한 것으로 간주되고을isinstance(o, collections.abc.Iterable)
반환True
합니다. - 에서 반환 된 객체
__iter__
가 반복자가 아닌 경우iter
즉시 실패하고TypeError
. __getitem__
이전 버전과의 호환성을 위해 특수 처리가 존재합니다. Fluent Python에서 다시 인용 :
이것이 모든 파이썬 시퀀스가 반복 가능한 이유입니다 : 모두
__getitem__
. 사실, 표준 시퀀스도 구현__iter__
하고 당신 도 구현 해야합니다.의 특수 처리는__getitem__
이전 버전과의 호환성을 위해 존재하고 나중에 사라질 수 있기 때문입니다 (이 글을 쓸 때 더 이상 사용되지는 않지만).
이것으로는 충분하지 않습니다.에서 반환 된 객체 __iter__
는 반복 프로토콜 (즉, next
메서드)을 구현해야합니다 . 설명서 의 관련 섹션을 참조하십시오 .
Python에서 좋은 방법은 "확인"대신 "시도하고 보는"것입니다.
Python <= 2.5에서는 할 수없고해서는 안됩니다. iterable은 "비공식적 인"인터페이스였습니다.
그러나 Python 2.6 및 3.0부터는 collections 모듈에서 사용할 수있는 일부 내장 ABC와 함께 새로운 ABC (추상 기본 클래스) 인프라를 활용할 수 있습니다.
from collections import Iterable
class MyObject(object):
pass
mo = MyObject()
print isinstance(mo, Iterable)
Iterable.register(MyObject)
print isinstance(mo, Iterable)
print isinstance("abc", Iterable)
이제 이것이 바람직하든 실제로 작동하든 관습에 불과합니다. 보시다시피 반복 불가능한 객체를 Iterable로 등록 할 수 있습니다. 그러면 런타임에 예외가 발생합니다. 따라서 isinstance는 "새로운"의미를 얻습니다. "선언 된"유형 호환성을 확인하기 만하면 파이썬으로 이동하는 좋은 방법입니다.
반면에 객체가 필요한 인터페이스를 충족하지 않으면 어떻게 하시겠습니까? 다음 예를 살펴보십시오.
from collections import Iterable
from traceback import print_exc
def check_and_raise(x):
if not isinstance(x, Iterable):
raise TypeError, "%s is not iterable" % x
else:
for i in x:
print i
def just_iter(x):
for i in x:
print i
class NotIterable(object):
pass
if __name__ == "__main__":
try:
check_and_raise(5)
except:
print_exc()
print
try:
just_iter(5)
except:
print_exc()
print
try:
Iterable.register(NotIterable)
ni = NotIterable()
check_and_raise(ni)
except:
print_exc()
print
객체가 예상 한 내용을 충족하지 않으면 TypeError가 발생하지만 적절한 ABC가 등록 된 경우 검사는 유용하지 않습니다. 반대로 __iter__
메서드를 사용할 수있는 경우 Python은 해당 클래스의 객체를 Iterable로 자동 인식합니다.
따라서 반복 가능한 것을 기대하는 경우 반복하고 잊어 버리십시오. 반면에 입력 유형에 따라 다른 작업을 수행해야하는 경우 ABC 인프라가 매우 유용 할 수 있습니다.
try:
#treat object as iterable
except TypeError, e:
#object is not actually iterable
당신의 오리가 정말로 오리인지 확인하기 위해 검사를 실행하지 말고 그것이 반복 가능한지 아닌지 확인하고, 그것이있는 것처럼 취급하고 그렇지 않은 경우 불평하십시오.
지금까지 찾은 최고의 솔루션 :
hasattr(obj, '__contains__')
기본적으로 객체가 in
연산자를 구현하는지 확인합니다 .
장점 (다른 솔루션에는 세 가지가 모두 없음) :
- 그것은 표현식입니다 ( try ... except 변형 과 달리 lambda 로 작동합니다 )
- 그것이 포함한 모든 반복 가능 객체에 의해 구현 (한다)는 스트링 (반대
__iter__
) - 모든 Python> = 2.5에서 작동
메모:
- "권한이 아닌 용서 요청"이라는 파이썬 철학은 예를 들어 목록에서 반복 가능 항목과 반복 불가능 항목이 모두 있고 유형에 따라 각 요소를 다르게 처리해야하는 경우 제대로 작동하지 않습니다 (try 및 non- 예외적으로 iterables 는 작동하지만 엉덩이가 추하고 오해의 소지가 있습니다)
- 반복 가능한지 확인하기 위해 객체 (예 : [x for x in obj])를 실제로 반복하려고 시도하는이 문제에 대한 솔루션은 큰 이터 러블에 대해 상당한 성능 페널티를 유발할 수 있습니다 (특히 이터 러블의 처음 몇 요소 만 필요한 경우, 예) 피해야합니다
이것을 시도해 볼 수 있습니다.
def iterable(a):
try:
(x for x in a)
return True
except TypeError:
return False
반복되는 생성기를 만들 수 있다면 (하지만 생성기를 사용하지 않아 공간을 차지하지 않음) 반복 가능합니다. "duh"종류의 것 같습니다. 처음에 변수가 반복 가능한지 확인해야하는 이유는 무엇입니까?
Python 3.5 부터 유형 관련 항목에 대해 표준 라이브러리의 유형 지정 모듈을 사용할 수 있습니다 .
from typing import Iterable
...
if isinstance(my_item, Iterable):
print(True)
isiterable = lambda obj: isinstance(obj, basestring) \
or getattr(obj, '__iter__', False)
Python 2 Glossary 에 따르면 반복 가능 항목은 다음과 같습니다.
모든 시퀀스 유형 (예 :
list
,str
및tuple
)과dict
및file
및 및__iter__()
또는__getitem__()
메서드로 정의한 모든 클래스의 객체와 같은 일부 비 시퀀스 유형 . Iterables는 for 루프와 시퀀스가 필요한 다른 많은 장소 (zip (), map (), ...)에서 사용할 수 있습니다. 반복 가능한 객체가 내장 함수 iter ()에 인수로 전달되면 객체의 반복자를 반환합니다.
물론,“허가보다 용서를 구하는 것이 더 쉽다”는 사실을 기반으로 한 파이썬의 일반적인 코딩 스타일을 감안할 때 일반적인 기대는 사용하는 것입니다.
try:
for i in object_in_question:
do_something
except TypeError:
do_something_for_non_iterable
그러나 명시 적으로 확인해야하는 경우 .NET에서 iterable을 테스트 할 수 있습니다 hasattr(object_in_question, "__iter__") or hasattr(object_in_question, "__getitem__")
. str
s에는 __iter__
메서드 가 없기 때문에 (적어도 Python 2에는없고 Python 3에서는 그렇습니다) generator
객체에 메서드 가 없기 때문에 둘 다 확인해야합니다 __getitem__
.
종종 스크립트 내에서 iterable
함수 를 정의하는 것이 편리하다는 것을 알게 됩니다. (이제 Alfe의 제안 된 단순화를 통합합니다) :
import collections
def iterable(obj):
return isinstance(obj, collections.Iterable):
그래서 어떤 객체가 매우 읽기 쉬운 형태로 반복 가능한지 테스트 할 수 있습니다.
if iterable(obj):
# act on iterable
else:
# not iterable
callable
함수를 사용하는 것처럼
편집 : numpy가 설치되어 있으면 간단히 할 수 있습니다 : from numpy import iterable
, 이것은 단순히 다음과 같습니다.
def iterable(obj):
try: iter(obj)
except: return False
return True
numpy가없는 경우이 코드 또는 위의 코드를 구현할 수 있습니다.
pandas 에는 다음과 같은 내장 기능이 있습니다.
from pandas.util.testing import isiterable
def is_iterable(x):
try:
0 in x
except TypeError:
return False
else:
return True
이것은 모든 반복 가능한 객체에 대해 예 라고 말하지만 Python 2의 문자열에는 아니오라고 말합니다 . (예를 들어 재귀 함수가 문자열이나 문자열 컨테이너를 취할 수있을 때 제가 원하는 것입니다. 그런 상황에서 용서 를 구하면 난독 코드가 발생할 수 있으며 먼저 권한을 요청하는 것이 좋습니다.)
import numpy
class Yes:
def __iter__(self):
yield 1;
yield 2;
yield 3;
class No:
pass
class Nope:
def __iter__(self):
return 'nonsense'
assert is_iterable(Yes())
assert is_iterable(range(3))
assert is_iterable((1,2,3)) # tuple
assert is_iterable([1,2,3]) # list
assert is_iterable({1,2,3}) # set
assert is_iterable({1:'one', 2:'two', 3:'three'}) # dictionary
assert is_iterable(numpy.array([1,2,3]))
assert is_iterable(bytearray("not really a string", 'utf-8'))
assert not is_iterable(No())
assert not is_iterable(Nope())
assert not is_iterable("string")
assert not is_iterable(42)
assert not is_iterable(True)
assert not is_iterable(None)
여기에있는 다른 많은 전략은 현에 예라고 말할 것입니다. 그것이 당신이 원하는 것이라면 사용하십시오.
import collections
import numpy
assert isinstance("string", collections.Iterable)
assert isinstance("string", collections.Sequence)
assert numpy.iterable("string")
assert iter("string")
assert hasattr("string", '__getitem__')
참고 : is_iterable ()은 bytes
및 유형의 문자열에 대해 yes라고 표시합니다 bytearray
.
bytes
Python 3의 객체는 반복 가능True == is_iterable(b"string") == is_iterable("string".encode('utf-8'))
합니다. Python 2에는 이러한 유형이 없습니다.bytearray
Python 2 및 3의 객체는 반복 가능합니다.True == is_iterable(bytearray(b"abc"))
OP hasattr(x, '__iter__')
접근 방식은 Python 3의 문자열에 대해 yes라고 말하고 Python 2에서는 no로 표시합니다 ( ''
또는 b''
또는 여부에 관계없이 u''
). @LuisMasuelli에게 감사드립니다 __iter__
.
파이썬이 왜 가지고 있는지 항상 알 수 callable(obj) -> bool
없지만 iterable(obj) -> bool
...
확실히 hasattr(obj,'__call__')
느리더라도 수행하기가 더 쉽습니다 .
거의 모든 다른 답변에서 try
/ 사용을 권장하기 때문에 except TypeError
예외 테스트는 일반적으로 모든 언어에서 나쁜 관행으로 간주되므로 여기에 iterable(obj) -> bool
내가 더 좋아하고 자주 사용 하는 구현이 있습니다.
파이썬 2의 위해, 나는 ... 그냥 여분의 성능 향상을 위해 람다를 사용합니다
(파이썬 3에서 당신이 함수를 정의하는 데 사용할 중요하지 않습니다 def
과 거의 같은 속도가 lambda
)
iterable = lambda obj: hasattr(obj,'__iter__') or hasattr(obj,'__getitem__')
이 함수는를 __iter__
테스트하지 않기 때문에 객체에 대해 더 빠르게 실행 됩니다 __getitem__
.
대부분의 반복 가능한 객체는 __iter__
특별한 경우 객체가로 돌아가는 위치에 의존해야 __getitem__
하지만 객체가 반복 가능하려면 둘 중 하나가 필요합니다.
(그리고 이것은 표준이므로 C 객체에도 영향을 미칩니다)
파이썬의 덕 타이핑을 존중하는 가장 쉬운 방법 은 오류를 잡는 것입니다 (파이썬은 객체가 반복자가 될 것으로 기대하는 것을 완벽하게 알고 있습니다) :
class A(object):
def __getitem__(self, item):
return something
class B(object):
def __iter__(self):
# Return a compliant iterator. Just an example
return iter([])
class C(object):
def __iter__(self):
# Return crap
return 1
class D(object): pass
def iterable(obj):
try:
iter(obj)
return True
except:
return False
assert iterable(A())
assert iterable(B())
assert iterable(C())
assert not iterable(D())
참고 :
- 객체가 반복 불가능한지 또는
__iter__
예외 유형이 동일한 경우 버그 가 구현 되었는지 여부는 구별과 관련이 없습니다 . 어쨌든 객체를 반복 할 수 없습니다. 나는 당신의 우려를 이해한다고 생각합니다. 내 개체에 대해 정의되지 않은 if를 발생
callable
시키기 위해 덕 타이핑에 의존 할 수 있다면 검사로 어떻게 존재 하지만 반복 가능한 검사의 경우는 그렇지 않습니까?AttributeError
__call__
나는 대답을 모르지만, 내가 (및 다른 사용자) 제공 한 함수를 구현하거나 코드에서 예외를 포착 할 수 있습니다 (해당 부분의 구현은 내가 작성한 함수와 같을 것입니다. 나머지 코드에서 반복자 생성을 통해 예외를 캡처하고 다른
TypeError
.
isiterable
다음 코드 의 func는 True
객체가 반복 가능한 경우 반환 합니다. 반복 할 수없는 경우 반환False
def isiterable(object_):
return hasattr(type(object_), "__iter__")
예
fruits = ("apple", "banana", "peach")
isiterable(fruits) # returns True
num = 345
isiterable(num) # returns False
isiterable(str) # returns False because str type is type class and it's not iterable.
hello = "hello dude !"
isiterable(hello) # returns True because as you know string objects are iterable
__iter__
속성 을 확인하는 대신 __len__
문자열을 포함하여 모든 파이썬 내장 iterable에 의해 구현되는 속성을 확인할 수 있습니다.
>>> hasattr(1, "__len__")
False
>>> hasattr(1.3, "__len__")
False
>>> hasattr("a", "__len__")
True
>>> hasattr([1,2,3], "__len__")
True
>>> hasattr({1,2}, "__len__")
True
>>> hasattr({"a":1}, "__len__")
True
>>> hasattr(("a", 1), "__len__")
True
반복 불가능한 객체는 명백한 이유로 이것을 구현하지 않습니다. 그러나이를 구현하지 않는 사용자 정의 이터 러블이나 iter
처리 할 수 있는 생성기 표현식은 포착하지 않습니다 . 그러나 이것은 한 줄로 수행 할 수 있으며 or
생성기에 대한 간단한 표현식 검사를 추가하면 이 문제를 해결할 수 있습니다. (쓰기 type(my_generator_expression) == generator
는 NameError
. 대신 이 답변을 참조하십시오 .)
다음 유형에서 GeneratorType을 사용할 수 있습니다.
>>> import types >>> types.GeneratorType <class 'generator'> >>> gen = (i for i in range(10)) >>> isinstance(gen, types.GeneratorType) True
--- utdemir가 수락 한 답변
(이것은 len
객체를 호출 할 수 있는지 확인하는 데 유용합니다 .)
파티에 좀 늦었지만 나는 스스로에게이 질문을했고 이것이 답을 생각하는 것을 보았다. 누군가가 이미 이것을 게시했는지 모르겠습니다. 그러나 본질적으로 모든 반복 가능한 유형은 dict에 " getitem " 이 있음을 알았습니다 . 이것은 시도하지 않고도 객체가 반복 가능한지 확인하는 방법입니다. (펀 의도)
def is_attr(arg):
return '__getitem__' in dir(arg)
실제로 "올바른" 것은 아니지만 문자열, 튜플, 부동 소수점 등과 같은 가장 일반적인 유형의 빠른 검사 역할을 할 수 있습니다.
>>> '__iter__' in dir('sds')
True
>>> '__iter__' in dir(56)
False
>>> '__iter__' in dir([5,6,9,8])
True
>>> '__iter__' in dir({'jh':'ff'})
True
>>> '__iter__' in dir({'jh'})
True
>>> '__iter__' in dir(56.9865)
False
참고 URL : https://stackoverflow.com/questions/1952464/in-python-how-do-i-determine-if-an-object-is-iterable
'Programing' 카테고리의 다른 글
iOS에서 상태 표시 줄 텍스트 색상을 변경하는 방법 (0) | 2020.09.28 |
---|---|
에뮬레이터는 어떻게 작동하며 어떻게 작성됩니까? (0) | 2020.09.28 |
MD5 해시를 생성하려면 어떻게해야합니까? (0) | 2020.09.28 |
이미 디스크에서 삭제 된 Git 리포지토리에서 여러 파일 제거 (0) | 2020.09.28 |
정의되지 않은 동작 및 시퀀스 포인트 (0) | 2020.09.28 |