단일 항목 또는 이중 항목이 될 수있는 인수를받는 함수가 있습니다.
def iterable(arg)
if #arg is an iterable:
print "yes"
else:
print "no"
그래서:
>>> iterable (( "f", "f")) 예 >>> 반복 가능 ([ "f", "f"]) 예 >>> iterable ( "ff") 아니
문제는 문자열이 기술적으로 반복 가능하므로 시도 할 때 ValueError를 잡을 수 없다는 것 arg[1]
입니다. isinstance ()는 좋은 습관이 아니기 때문에 사용하고 싶지 않습니다.
답변
isinstance 사용 (왜 나쁜 습관인지 모르겠습니다)
import types
if not isinstance(arg, types.StringTypes):
StringTypes 사용에 유의하십시오. 모호한 유형의 문자열을 잊지 않도록합니다.
장점은 파생 된 문자열 클래스에서도 작동합니다.
class MyString(str):
pass
isinstance(MyString(" "), types.StringTypes) # true
또한이 이전 질문을 살펴볼 수도 있습니다 .
건배.
NB : 행동이 파이썬 3으로 변경 StringTypes
하고 basestring
더 이상 정의되지 않습니다. 필요에 따라, 당신은에 장착 할 수 isinstance
에 의해 str
, 또는 부분 집합의 튜플 (str, bytes, unicode)
사이 썬 사용자를위한, 예. 으로 @Theron Luhn는 했나요, 당신은 또한 사용할 수 있습니다 six
.
답변
2017 년 현재 모든 버전의 Python에서 작동하는 휴대용 솔루션은 다음과 같습니다.
#!/usr/bin/env python
import collections
import six
def iterable(arg):
return (
isinstance(arg, collections.Iterable)
and not isinstance(arg, six.string_types)
)
# non-string iterables
assert iterable(("f", "f")) # tuple
assert iterable(["f", "f"]) # list
assert iterable(iter("ff")) # iterator
assert iterable(range(44)) # generator
assert iterable(b"ff") # bytes (Python 2 calls this a string)
# strings or non-iterables
assert not iterable(u"ff") # string
assert not iterable(44) # integer
assert not iterable(iterable) # function
답변
추상 기본 클래스가 도입 된 Python 2.6 이후 isinstance
(구체적인 클래스가 아닌 ABC에서 사용됨)는 이제 완벽하게 허용되는 것으로 간주됩니다. 구체적으로 특별히:
from abc import ABCMeta, abstractmethod
class NonStringIterable:
__metaclass__ = ABCMeta
@abstractmethod
def __iter__(self):
while False:
yield None
@classmethod
def __subclasshook__(cls, C):
if cls is NonStringIterable:
if any("__iter__" in B.__dict__ for B in C.__mro__):
return True
return NotImplemented
이것은 (의 구현 세부 사항 )에 Iterable
정의 된 것과 정확히 일치하는 복사본 (클래스 이름 만 변경 )입니다 … 이것이 원하는대로 작동하는 이유 는 그렇지 않지만 후자는 문자열이 이 문 바로 다음에 명시 적 으로 호출하여 반복 가능한 것으로 간주됩니다 ._abcoll.py
collections.py
collections.Iterable
Iterable.register(str)
class
물론 정의에서 구체적으로 제외하려는 다른 클래스를 호출 하기 전에 __subclasshook__
반환 하여 쉽게 확장 할 수 있습니다.False
any
어떤 경우에, 당신은이 새로운 모듈을 가져온 후 myiter
, isinstance('ciao', myiter.NonStringIterable)
것 False
, 그리고 isinstance([1,2,3], myiter.NonStringIterable)
될 것입니다 True
추상 기본 클래스를 정의 … 파이썬 2.6 이상이 구현 수표에 적절한 방법으로 간주됩니다 – 당신이 요청하는대로, 확인 isinstance
하십시오.
답변
나는 이것이 오래된 게시물이라는 것을 알고 있지만 인터넷 후손에 대한 나의 접근 방식을 추가 할 가치가 있다고 생각했습니다. 아래 함수는 대부분의 경우 Python 2와 3 모두에서 작동하는 것 같습니다.
def is_collection(obj):
""" Returns true for any iterable which is not a string or byte sequence.
"""
try:
if isinstance(obj, unicode):
return False
except NameError:
pass
if isinstance(obj, bytes):
return False
try:
iter(obj)
except TypeError:
return False
try:
hasattr(None, obj)
except TypeError:
return True
return False
이것은 두 번째 인수가 문자열이나 유니 코드 문자열이 아닐 때 hasattr
a를 TypeError
발생 시키는 내장을 사용하여 (mis)에 의해 문자열이 아닌 이터 러블을 확인 합니다.
답변
이전 답변을 결합하여 다음을 사용합니다.
import types
import collections
#[...]
if isinstance(var, types.StringTypes ) \
or not isinstance(var, collections.Iterable):
#[Do stuff...]
100 % 어리석은 증거는 아니지만 객체가 반복 가능하지 않은 경우에도 여전히 전달하고 덕 타이핑으로 돌아갈 수 있습니다.
편집 : Python3
types.StringTypes == (str, unicode)
. Phython3에 해당하는 것은 다음과 같습니다.
if isinstance(var, str ) \
or not isinstance(var, collections.Iterable):
답변
2.x
나는 제안했을 것이다 :
hasattr(x, '__iter__')
또는 David Charles의 주석이 Python3에 대해 이것을 조정 한 것을 고려하여 다음과 같습니다.
hasattr(x, '__iter__') and not isinstance(x, (str, bytes))
3.x
내장 basestring
추상 유형 이 제거되었습니다 . str
대신 사용하십시오 . str
및 bytes
유형은 공유 기본 클래스를 보증하는 공통 기능 충분하지 않습니다.
답변
올바르게 지적했듯이 단일 문자열은 문자 시퀀스입니다.
그래서 당신이 정말로하고 싶은 것은 arg
isinstance 또는 type (a) == str을 사용하여 어떤 종류의 시퀀스인지 알아내는 것 입니다.
가변적 인 양의 매개 변수를 사용하는 함수를 구현하려면 다음과 같이해야합니다.
def function(*args):
# args is a tuple
for arg in args:
do_something(arg)
function ( “ff”) 및 function ( “ff”, “ff”)가 작동합니다.
당신과 같은 isiterable () 함수가 필요한 시나리오를 볼 수 없습니다. 나쁜 스타일은 isinstance ()가 아니라 isinstance ()를 사용해야하는 상황입니다.