2012-06-26 8 views
32

내가 좋아하는 일을했다 오래된 파이썬 코드를 발견했다.python의 isinstance()를 사용하여 변수가 숫자인지 제대로 확인하는 방법은 무엇입니까? <code>pep8</code>이 <code>isinstance()</code>이 추천 사용에 대한 불평, 예상대로</p> <pre><code>if type(var) is type(1): ... </code></pre> <p>:

이제 문제는 numbers 모듈은 파이썬 2.6에 추가 된 내가 그래서 if isinstance(var, Numbers.number)는 해결책이 아니다

파이썬 2.5 +와 함께 작동 코드를 작성해야합니다.

이 경우 적절한 해결책은 무엇입니까? int, floatcomplex

>>> num = 10 
>>> if isinstance(num, (int, float, long, complex)): #use tuple if checking against multiple types 
     print('yes it is a number') 

yes it is a number 
>>> isinstance(num, float) 
False 
>>> isinstance(num, int) 
True 
>>> a = complex(1, 2) 
>>> isinstance(a, complex) 
True 
+0

numpy를 기꺼이 사용하려면 'numpy.isfinite'가 트릭을해야합니다. –

답변

83

당신은 types module 사용할 수 있습니다 :

+3

'isinstance()'는 객체들의 튜플을 취할 수 있습니까? Woah, dude ... –

+0

@Def_Os : 예, 이것은 Python 2.2 이후의 기능입니다. –

+0

정말 답의 맨 위에 붙여야합니다. –

13

파이썬 2 longcomplexpython 3.x 3 지원 번호 int, float에 대한 네 가지 유형의 지원

>>> import types 
>>> var = 1 
>>> NumberTypes = (types.IntType, types.LongType, types.FloatType, types.ComplexType) 
>>> isinstance(var, NumberTypes) 
True 

주를 여러 유형에 대해 테스트 할 때 튜플을 사용합니다. 후드 아래에서

IntTypeint 단지 별칭 등 :

>>> isinstance(var, (int, long, float, complex)) 
True 

complex 유형이 파이썬이 복잡한 숫자에 대한 지원과 함께 컴파일해야합니다입니다 당신은/except 블록이 사용 시도에 대한 보호하려는 경우 :

>>> try: 
...  NumberTypes = (types.IntType, types.LongType, types.FloatType, types.ComplexType) 
... except AttributeError: 
...  # No support for complex numbers compiled 
...  NumberTypes = (types.IntType, types.LongType, types.FloatType) 
... 

을 그냥 직접 유형 사용하는 경우 나 :

>>> try: 
...  NumberTypes = (int, long, float, complex) 
... except NameError: 
...  # No support for complex numbers compiled 
...  NumberTypes = (int, long, float) 
... 

마지막으로를, 당신의 numbers.Numbers abstract base type (새을 사용할 수 있습니다 파이썬 2.6)도 위의 유형에서 직접 파생되지 않는 사용자 정의 숫자 형식 지원 :

>>> import numbers 
>>> isinstance(var, numbers.Number) 
True 

이 모듈을 complex 유형이 사용된다는 가정을 만드는가를; 그렇지 않으면 가져 오기 오류가 발생합니다.

2

duck typing에 사용하는 방식에 따라 더 나은 방법이 될 수 있습니다 (certainlycommonlyrecommended). 마르틴 피터스 (Martijn Pieters)의 접근법에 대한 문제점은 당신이 항상 목록에서 몇 가지 유형의 번호를 놓치게된다는 것입니다. 내 머리 꼭대기에서 sympy 유리수, 임의의 정밀도 정수 및 복소수 구현과 같은 코드는 작동하지 않습니다.

def is_number(thing): 
    try: 
     thing + 1 
     return True 
    except TypeError: 
     return False 

이 코드는 숫자의 합리적인 구현과 작동합니다 :

하나의 대안이 같은 함수를 작성하는 것입니다. 물론 중요한 단점이 있습니다. 또한 숫자가 아닌 숫자를 무리하게 구현하면 작동합니다 (예 : 더하기 연산자가 오버로드되어 정수를 허용하는 경우).

또 다른 대안은 (숫자가 무엇인지 알아야하는 이유에 따라) 그냥 숫자라고 가정하는 것입니다. 그렇지 않으면 숫자가 필요한 코드로 오류가 발생합니다.

나는이 접근법이 항상 (사람들과는 달리 ...) 고려하는 가치가 있다고 말하는 것은 아닙니다.