isiterable
같은 방법이 있습니까? 지금까지 찾은 유일한 해결책은 전화하는 것입니다.
hasattr(myObj, '__iter__')
그러나 이것이 얼마나 어리석은 것인지 잘 모르겠습니다.
질문자 :willem
isiterable
같은 방법이 있습니까? 지금까지 찾은 유일한 해결책은 전화하는 것입니다.
hasattr(myObj, '__iter__')
그러나 이것이 얼마나 어리석은 것인지 잘 모르겠습니다.
__iter__
확인은 시퀀스 유형에서 작동하지만 예를 들어 Python 2의 문자열에서는 실패합니다. 나도 정답을 알고 싶습니다. 그때까지 여기에 한 가지 가능성이 있습니다(문자열에서도 작동함).
from __future__ import print_function try: some_object_iterator = iter(some_object) except TypeError as te: print(some_object, 'is not iterable')
iter
내장은 __iter__
메서드 또는 문자열의 경우 __getitem__
메서드를 확인합니다.
또 다른 일반적인 파이썬 접근 방식은 iterable을 가정한 다음 주어진 객체에서 작동하지 않으면 정상적으로 실패하는 것입니다. 파이썬 용어집:
그 방법 또는 속성 서명 검사를 통해서가 아니라 강조 인터페이스에 의해 어떤 종류의 객체 ( "오리처럼 외모와 오리처럼 꽥꽥 경우, 오리해야합니다.")에 명시 적 관계에 의해 객체의 유형을 결정하는 파이썬 프로그래밍 스타일 특정 유형이 아닌 잘 설계된 코드는 다형성 대체를 허용하여 유연성을 향상시킵니다. 덕 타이핑은 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
루프를 사용할 때 어떤 일이 발생하는지에 대한 빠른 알림과 함께 사실을 설명하기 위한 토론이 이어집니다.
다음 조건 중 하나 이상이 참이면 iter(o)
를 호출 o
에서 반복자를 얻을 수 있습니다.
a) o
에는 반복자 객체를 반환하는 __iter__
__iter__
및 __next__
(Python 2: next
) 메서드가 있는 모든 객체입니다.
b) o
에는 __getitem__
메서드가 있습니다.
Iterable
또는 Sequence
의 인스턴스를 __iter__
속성을 확인하는 것만으로는 충분하지 않습니다.
객체 o
__getitem__
만 구현하고 __iter__
구현하지 않는 경우 iter(o)
는 인덱스 0에서 시작하여 정수 인덱스 o
에서 항목을 가져 IndexError
발생 StopIteration
다음 StopIteration 자체를 발생시킵니다.
iter
가 반환한 iterator가 정상적인지 확인할 수 있는 방법은 시도하는 것 외에는 없습니다.
객체 o
가 __iter__
구현하면 iter
__iter__
가 반환한 객체가 반복자인지 확인합니다. __getitem__
만 구현하는 경우 온전성 검사가 없습니다.
__iter__
이깁니다. 객체 o
__iter__
와 __getitem__
모두 구현하면 iter(o)
__iter__
를 호출합니다.
자신의 객체를 반복 가능하게 만들고 싶다면 항상 __iter__
메서드를 구현하세요.
for
따라가기 위해서는 Python에서 for
루프를 사용할 때 어떤 일이 발생하는지 이해해야 합니다. 이미 알고 있는 경우 다음 섹션으로 건너뛰어도 됩니다.
당신이 사용하는 경우 for item in o
몇 가지 반복 가능한 객체에 대한 o
, 파이썬은 호출 iter(o)
반환 값으로 반복자 객체를 기대하고있다. __next__
(또는 Python 2에서는 next
__iter__
메서드를 구현하는 모든 객체입니다.
관례에 따라 __iter__
메서드는 객체 자체를 반환해야 합니다(즉, return self
). next
Python은 StopIteration
이 발생할 때까지 반복자에서 next를 호출합니다. 이 모든 것이 암시적으로 발생하지만 다음 데모에서는 이를 볼 수 있습니다.
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>
그러나 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
책에서 직접 인용:
x
가 반복 가능한지 확인하는 가장 정확한 방법iter(x)
를 호출하고 그렇지 않은 경우TypeError
예외를 처리하는 것입니다.iter(x)
는 레거시__getitem__
메서드Iterable
ABC는 고려하지 않기 때문에isinstance(x, abc.Iterable)
사용하는 것보다 더 정확합니다.
__getitem__
__iter__
는 제공하지 않는 객체에 대한 반복
BasicIterable
의 인스턴스에 대한 반복 IndexError
가 발생할 때까지 0에서 시작하여 인덱스별로 항목을 가져오려고 시도하는 반복기를 생성합니다. 데모 객체의 __getitem__
iter
반환한 반복자 __getitem__(self, item)
에 인수로 제공 item
을 단순히 반환합니다.
>>> 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
iterator는 다음 항목을 반환할 수 없을 때 StopIteration
item == 3
대해 발생 IndexError
는 내부적으로 처리됩니다. for
루프를 사용하여 BasicIterable
을 반복하는 것이 예상대로 작동하는 이유입니다.
>>> 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__
(또는 Python 2에서는 next
__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
__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__
__getitem__
이면 충분할 list
__iter__
메서드를 구현하는 이유를 스스로에게 물어볼 수 있습니다.
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
__iter__
를 구현해야 하는 이유는 다음과 같습니다.
__iter__
를 구현하면 인스턴스가 반복 가능한 것으로 간주되고 isinstance(o, collections.abc.Iterable)
True
를 반환합니다.__iter__
가 반환한 객체가 반복자가 아닌 경우 iter
는 즉시 실패하고 TypeError
가 발생합니다.__getitem__
의 특별한 처리는 이전 버전과의 호환성을 위해 존재합니다. Fluent Python에서 다시 인용:이것이 모든 Python 시퀀스가 반복 가능한 이유입니다.
__getitem__
사실, 표준 시퀀스는__iter__
도 구현하고 여러분의 것도 그렇게 해야 합니다.__getitem__
의 특별한 처리는 이전 버전과의 호환성을 위해 존재하고 앞으로 사라질 수 있기 때문입니다(이 글을 쓰는 동안 더 이상 사용되지 않음).
나는 최근에 이 문제를 꽤 많이 연구하고 있다. 내 결론에 따르면 요즘에는 이것이 최선의 접근 방식입니다.
from collections.abc import Iterable # drop `.abc` with Python 2.7 or lower def iterable(obj): return isinstance(obj, Iterable)
위의 내용은 이미 이전에 권장되었지만 iter()
를 사용하는 것이 더 낫다는 일반적인 합의가 있었습니다.
def iterable(obj): try: iter(obj) except Exception: return False else: return True
iter()
를 사용 __getitem__
만 반복 가능한 것으로 간주되는 객체에 점점 짜증이 나기 시작했습니다. __getitem__
이 있어야 하는 타당한 이유가 있으며 그와 함께 위의 코드가 제대로 작동하지 않습니다. 실생활의 예로 Faker 를 사용할 수 있습니다. 위의 코드는 반복 가능하다고 보고하지만 실제로 반복하려고 하면 AttributeError
발생합니다(Faker 4.0.2에서 테스트됨):
>>> from faker import Faker >>> fake = Faker() >>> iter(fake) # No exception, must be iterable <iterator object at 0x7f1c71db58d0> >>> list(fake) # Ooops Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/home/.../site-packages/faker/proxy.py", line 59, in __getitem__ return self._factory_map[locale.replace('-', '_')] AttributeError: 'int' object has no attribute 'replace'
insinstance()
사용한다면 실수로 Faker 인스턴스(또는 __getitem__
만 있는 다른 객체)를 반복 가능한 것으로 간주하지 않을 것입니다.
>>> from collections.abc import Iterable >>> from faker import Faker >>> isinstance(Faker(), Iterable) False
이전 답변에서는 Python에서 반복을 구현하는 이전 방법이 __getitem__
을 기반으로 하고 isinstance()
접근 방식이 이를 감지하지 못하기 때문에 iter()
를 사용하는 것이 더 안전하다고 언급했습니다. 이것은 오래된 Python 버전에서 사실일 수 있지만, 나의 철저한 테스트를 기반으로 하는 isinstance()
는 요즘 잘 작동합니다. isinstance()
가 작동하지 않았지만 iter()
가 작동한 유일한 경우 UserDict
를 사용하는 것이었습니다. 관련이 있는 경우 isinstance(item, (Iterable, UserDict))
를 사용하여 이를 처리할 수 있습니다.
Python 3.5 부터 유형 관련 항목에 대해 표준 라이브러리 의 타이핑 모듈을 사용할 수 있습니다.
from typing import Iterable ... if isinstance(my_item, Iterable): print(True)
이것으로는 충분하지 않습니다: __iter__
의해 반환된 객체는 반복 프로토콜(즉, next
메소드)을 구현해야 합니다. 설명서 의 관련 섹션을 참조하십시오.
Python에서는 "확인" 대신 "시도하고 확인"하는 것이 좋습니다.
Python <= 2.5에서는 할 수 없고 해서는 안 됩니다. iterable은 "비공식적인" 인터페이스였습니다.
그러나 Python 2.6 및 3.0부터 컬렉션 모듈에서 사용할 수 있는 일부 내장 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는 "새로운" 의미를 얻습니다. "선언된" 유형 호환성을 확인하기만 하면 됩니다. 이는 Python에서 사용하기에 좋은 방법입니다.
반면에 개체가 필요한 인터페이스를 충족하지 않으면 어떻게 하시겠습니까? 다음 예를 들어보세요.
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로 자동 인식합니다.
따라서 iterable을 기대한다면 반복하고 잊어 버리십시오. 반면에 입력 유형에 따라 다른 작업을 수행해야 하는 경우 ABC 인프라가 매우 유용할 수 있습니다.
try: #treat object as iterable except TypeError, e: #object is not actually iterable
오리가 정말 오리인지 확인하기 위해 검사를 실행하여 반복 가능한지 여부를 확인하지 말고 있는 것처럼 처리하고 그렇지 않은 경우 불평하십시오.
당신은 이것을 시도할 수 있습니다:
def iterable(a): try: (x for x in a) return True except TypeError: return False
반복하는 생성기를 만들 수 있다면(그러나 생성기를 사용하지 않아 공간을 차지하지 않음), 반복 가능합니다. '으음' 그런 것 같습니다. 처음에 변수가 반복 가능한지 확인해야 하는 이유는 무엇입니까?
지금까지 찾은 최고의 솔루션:
hasattr(obj, '__contains__')
기본적으로 개체가 in
연산자를 구현하는지 확인합니다.
장점 (다른 솔루션에는 세 가지 모두가 포함되어 있지 않음):
__iter__
와 반대되는) 문자열을 포함하여 모든 iterable에 의해 구현되어야 합니다 (반드시)노트:
여기 에서 좋은 해결책을 찾았습니다.
isiterable = lambda obj: isinstance(obj, basestring) \ or getattr(obj, '__iter__', False)
Python 2 Glossary 에 따르면 iterable은 다음과 같습니다.
모든 시퀀스 유형(예:
list
,str
및tuple
dict
및file
과 같은 일부 비시퀀스 유형__iter__()
또는__getitem__()
메서드로 정의한 클래스의 객체. Iterables는 for 루프와 시퀀스가 필요한 다른 많은 위치(zip(), map(), ...)에서 사용할 수 있습니다. 반복 가능한 객체가 내장 함수 iter()에 인수로 전달되면 객체에 대한 반복자를 반환합니다.
물론, "허가보다 용서를 구하는 것이 더 쉽다"는 사실에 기반한 Python의 일반적인 코딩 스타일을 감안할 때 일반적인 기대는 다음을 사용하는 것입니다.
try: for i in object_in_question: do_something except TypeError: do_something_for_non_iterable
그러나 명시적으로 확인해야 하는 경우 hasattr(object_in_question, "__iter__") or hasattr(object_in_question, "__getitem__")
iterable을 테스트할 수 있습니다. str
__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
callable(obj) -> bool
있지만 iterable(obj) -> bool
없는 이유에 대해 항상 이해하지 못했습니다.
hasattr(obj,'__call__')
을 수행하는 것이 더 쉽습니다.
거의 모든 다른 답변이 try
/ except TypeError
사용을 권장하기 때문에 예외 테스트는 일반적으로 모든 언어에서 나쁜 습관으로 간주됩니다. 여기에 iterable(obj) -> bool
구현이 더 좋아지고 자주 사용하게 되었습니다.
파이썬 2를 위해 추가 성능 향상을 위해 람다를 사용할 것입니다...
(python 3에서는 함수를 정의하는 데 무엇을 사용하는지는 중요하지 않습니다. def
lambda
와 거의 같은 속도를 가집니다)
iterable = lambda obj: hasattr(obj,'__iter__') or hasattr(obj,'__getitem__')
__getitem__
테스트하지 않기 때문에 __iter__
가 있는 객체에 대해 더 빠르게 실행됩니다.
대부분의 반복 가능한 객체는 특수 케이스 객체가 __getitem__
__iter__
의존해야 하지만 객체가 반복 가능하려면 둘 중 하나가 필요합니다.
(그리고 이것이 표준이기 때문에 C 객체에도 영향을 미칩니다)
def is_iterable(x): try: 0 in x except TypeError: return False else: return True
이것은 모든 반복 가능한 객체에 대해 yes라고 말할 것이지만 Python 2의 문자열에는 no라고 말할 것입니다. (예를 들어 재귀 함수가 문자열 또는 문자열 컨테이너를 사용할 수 있을 때 내가 원하는 것입니다. 그런 상황에서 용서 를 구하면 난독화될 수 있으며 먼저 권한을 요청하는 것이 좋습니다.)
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__')
bytes
및 bytearray
유형의 문자열에 대해 yes라고 말합니다.
bytes
객체는 반복 가능합니다. True == is_iterable(b"string") == is_iterable("string".encode('utf-8'))
Python 2에는 그러한 유형이 없습니다.bytearray
객체는 반복 가능합니다. True == is_iterable(bytearray(b"abc"))
OP hasattr(x, '__iter__')
접근 방식은 Python 3에서는 문자열에 대해 yes, Python 2에서는 no라고 말합니다( ''
또는 b''
또는 u''
여부에 관계없이). @LuisMasuelli 덕분에 버그가 있는 __iter__
도 실망하게 됩니다.
Python의 오리 타이핑을 존중하는 가장 쉬운 방법은 오류를 잡는 것입니다(Python은 객체가 반복자가 되기 위해 무엇을 기대하는지 완벽하게 알고 있습니다).
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__
가 구현되었는지 여부는 구별과 관련이 없습니다. 어쨌든 객체를 반복할 수 없습니다. 어떻게 : 나는 당신의 우려를 이해 생각 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__
속성을 확인할 수 있습니다.
>>> 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
반복 불가능한 객체는 명백한 이유로 이것을 구현하지 않습니다. 그러나 그것을 구현하지 않는 사용자 정의 iterable이나 iter
가 처리할 수 있는 제너레이터 표현식은 catch하지 않습니다. 그러나 이것은 한 줄로 수행할 수 있으며 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
을 호출할 수 있는지 확인하는 데 유용합니다.)
실제로 "올바른" 것은 아니지만 문자열, 튜플, 부동 소수점 등과 같은 가장 일반적인 유형을 빠르게 확인할 수 있습니다.
>>> '__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
파티에 조금 늦었지만 나는 스스로에게 이 질문을 하고 이것을 보고 답을 생각했습니다. 누군가가 이미 이것을 게시했는지 모르겠습니다. 그러나 본질적으로 모든 반복 가능한 유형의 사전에 __getitem__()이 있다는 것을 알았습니다. 이것은 시도하지 않고도 객체가 반복 가능한지 확인하는 방법입니다. (말장난 의도)
def is_attr(arg): return '__getitem__' in dir(arg)
객체가 반복 가능한지 확인하는 많은 방법
from collections.abc import Iterable myobject = 'Roster' if isinstance(myobject , Iterable): print(f"{myobject } is iterable") else: print(f"strong text{myobject } is not iterable")
출처 : http:www.stackoverflow.com/questions/1952464/in-python-how-do-i-determine-if-an-object-is-iterable
git: 새 파일을 포함하여 모든 작업 디렉토리 변경 사항을 실행 취소합니다. (0) | 2023.04.28 |
---|---|
psql에서 데이터베이스를 전환하는 방법은 무엇입니까? (0) | 2023.04.28 |
두 날짜(일수)의 차이를 계산하시겠습니까? (1) | 2023.04.28 |
쉘 스크립트의 YYYY-MM-DD 형식 날짜 (0) | 2023.04.28 |
JavaScriptSerializer - 열거형을 문자열로 JSON 직렬화 (0) | 2023.04.28 |