파이썬에서 객체의 유형을 비교하는 방법은 무엇입니까?


163

기본적으로 나는 이것을하고 싶다 :

obj = 'str'
type ( obj ) == string

나는 시도했다 :

type ( obj ) == type ( string )

그리고 그것은 작동하지 않았다.

또한 다른 유형은 어떻습니까? 예를 들어, 나는 복제 할 수 없었다 NoneType.


이것은 작동합니다type(obj) == str
Joshua Varghese

답변:


241
isinstance()

귀하의 경우에는 isinstance("this is a string", str)을 반환 True합니다.

이것을 읽을 수도 있습니다 : http://www.canonical.org/~kragen/isinstance/


4
나는 당신 (OP)이 참조 된 링크를 반드시 읽어야 한다고 말하고 싶습니다 . 이것은 왜 객체의 유형을 확인하는 것이 일반적으로 나쁜 생각인지, 아마도 당신이 대신해야 할 일에 대한 많은 세부 정보를 제공합니다.
Jeff Shannon

2
str이 아닌 basestr을 사용해야합니다. 그렇지 않으면 유니 코드를 선택하지 않습니다. (3.x를 위해 나는 생각하지만, STR은 입니다 basestr)
하센

36

isinstance 공장:

if isinstance(obj, MyClass): do_foo(obj)

그러나 , 명심하십시오 : 오리처럼 보이고 오리처럼 들리면 오리입니다.

편집 : 없음 유형의 경우 간단하게 수행 할 수 있습니다.

if obj is None: obj = MyClass()

def distance_from_zero(n): if isinstance(n,int) or isinstance(n,float): return abs(n) else: return "Nope" print distance_from_zero(True) "Nope"대신 "1"을 반환합니다. 이 문제를 해결하는 방법?
dig_123

당신이 사용하려는 경우 isinstance그러나에 대해서도 확인 Noneisinstance(obj, (MyClass, type(None)))작동합니다.types.NoneType파이썬 3에서 제거되었으므로 type(None)참조를 얻는 것만 큼 ​​이식성이 없습니다 NoneType.
Santeri Paavolainen

33

먼저 모든 유형 비교를 피하십시오. 그것들은 매우, 거의 필요하지 않습니다. 때로는 함수에서 매개 변수 유형을 확인하는 데 도움이됩니다. 잘못된 유형의 데이터는 예외를 발생 시키므로 필요한 모든 것입니다.

모든 기본 변환 함수는 type 함수와 동일하게 매핑됩니다.

type(9) is int
type(2.5) is float
type('x') is str
type(u'x') is unicode
type(2+3j) is complex

다른 경우가 몇 가지 있습니다.

isinstance( 'x', basestring )
isinstance( u'u', basestring )
isinstance( 9, int )
isinstance( 2.5, float )
isinstance( (2+3j), complex )

BTW는 이러한 유형 검사가 필요하지 않습니다. None은 NoneType의 유일한 인스턴스입니다. None 객체는 싱글 톤입니다. 없음을 확인하십시오.

variable is None

BTW, 위의 일반적으로 사용하지 마십시오. 일반적인 예외와 파이썬의 고유 한 다형성을 사용하십시오.


3
DSL에서 입력의 유효성을 검사하는 경우이 모든 것이 필요합니다 NoneType. 매개 변수가 , 또는 ? str일 수있는 경우 확인하는 것보다 훨씬 깨끗합니다 . 지연된 계산을위한 도구를 작성하거나 길거나 리소스를 많이 사용하는 프로세스를 시작하려는 경우 일부 사용자 지정 유효성 검사 단계에서 미리 오류 를 포착하는 것이 좋습니다. 이것은 내가 작업했던 거의 모든 과학 컴퓨팅 프로젝트의 중요한 부분이었습니다. 내가 본 모든 개발 프로젝트 중에서 더 많은 것이 필요했습니다. unicodeNoneisinstance(x, (str, unicode, types.NoneType))Nonetype
ely

23

다른 유형의 경우 유형 모듈을 확인하십시오 .

>>> import types
>>> x = "mystring"
>>> isinstance(x, types.StringType)
True
>>> x = 5
>>> isinstance(x, types.IntType)
True
>>> x = None
>>> isinstance(x, types.NoneType)
True

PS 유형 검사는 나쁜 생각입니다.


15

알려진 유형의 무언가가 있는 type(x) == type(y)트릭을 항상 사용할 수 있습니다 y.

# check if x is a regular string
type(x) == type('')
# check if x is an integer
type(x) == type(1)
# check if x is a NoneType
type(x) == type(None)

종종 최근의 파이썬에서 더 좋은 방법이 있습니다. 그러나 한 가지만 기억하고 싶다면 기억할 수 있습니다.

이 경우 더 좋은 방법은 다음과 같습니다.

# check if x is a regular string
type(x) == str
# check if x is either a regular string or a unicode string
type(x) in [str, unicode]
# alternatively:
isinstance(x, basestring)
# check if x is an integer
type(x) == int
# check if x is a NoneType
x is None

마지막 경우에 주목하십시오 . NoneType파이썬에는 인스턴스가 하나뿐입니다 None. None 예외를 많이 입력하십시오 (TypeError: 'NoneType' object is unsubscriptable -항상 나에게 발생합니다.)

마지막으로 fengshaun이 지적했듯이 파이썬의 유형 검사는 항상 좋은 생각은 아닙니다. 값을 예상 한 유형처럼 사용하고 그 결과로 발생하는 예외를 포착 (또는 전파)하는 것이 더 비현실적입니다.


1
가치가있는 것에 대해 isinstance ()는 파이썬에서 유형을 확인하는 선호되는 방법입니다 (필요한 경우).
David Z

6

당신은 매우 가깝습니다! string유형이 아닌 모듈입니다. obj문자열의 유형 객체와 유형을 비교하려고 할 것입니다 str.

type(obj) == str  # this works because str is already a type

또는

type(obj) == type('')

파이썬 2에서 obj유니 코드 유형 인 경우 위의 어느 것도 작동하지 않습니다. 그렇습니다 isinstance(). 이 문제를 해결하는 방법은이 게시물에 대한 John의 의견을 참조하십시오. 지금 10 분 정도 기억하려고했지만 메모리 블록이있었습니다!


2
str과 유니 코드를 모두 얻으려면 isinstance ()와 함께 basestring을 사용하십시오.
John Fouhy

5

당신이 작성해야하기 때문입니다

s="hello"
type(s) == type("")

type은 인스턴스를 허용하고 해당 유형을 반환합니다. 이 경우 두 인스턴스 유형을 비교해야합니다.

사전 점검을 수행해야하는 경우 유형보다 지원되는 인터페이스를 점검하는 것이 좋습니다.

동일한 인터페이스를 구현하기 때문에 완전히 다른 유형의 완전히 다른 인스턴스를 가질 수 있다는 사실에 관계없이 코드는 특정 유형의 인스턴스를 원한다는 사실을 제외하고는 실제로 유형을 많이 알려주지 않습니다. .

예를 들어이 코드가 있다고 가정합니다.

def firstElement(parameter):
    return parameter[0]

자,이 코드가 튜플 만 허용하기를 원한다고 가정하십시오.

import types

def firstElement(parameter):
    if type(parameter) != types.TupleType:
         raise TypeError("function accepts only a tuple")
    return parameter[0]

이것은이 루틴의 재사용 성을 감소시킵니다. 목록, 문자열 또는 numpy.array를 전달하면 작동하지 않습니다. 더 나은 것

def firstElement(parameter):
    if not (hasattr(parameter, "__getitem__") and callable(getattr(parameter,"__getitem__"))):
        raise TypeError("interface violation")
    return parameter[0]

프로토콜이 만족스럽지 않으면 parameter [0]에서 예외가 발생합니다. 물론 부작용을 방지하거나 실패하기 전에 호출 할 수있는 호출을 복구하지 않는 한이 방법은 예외입니다. (견고한) 예, 요점을 지적하십시오.

def firstElement(parameter):
    if not (hasattr(parameter, "__getitem__") and callable(getattr(parameter,"__getitem__"))):
        raise TypeError("interface violation")
    os.system("rm file")
    return parameter[0]

이 경우 system () 호출을 실행하기 전에 코드에서 예외가 발생합니다. 인터페이스 검사가 없으면 파일을 제거한 다음 예외가 발생했을 것입니다.


인터페이스를 확인하는 실제 선호되는 방법을 표시해 주셔서 감사합니다. 여기에 많은 답변이 언급되어 있지만, 대신 좋은 것의 예를 제시하는 사람은 거의 없습니다. 그래도 여전히 내 개인적인 질문에 직접 대답하지는 않습니다 (의미가 많은 항목이 포함 된 문자열과 의미가없는 항목이 많이 포함 된 문자열 목록을 분리하려고합니다. 감사합니다!
Nick

5

문자열 대신 str을 사용하십시오.

type ( obj ) == str

설명

>>> a = "Hello"
>>> type(a)==str
True
>>> type(a)
<type 'str'>
>>>

4

나는 사용한다 type(x) == type(y)

예를 들어, 무언가를 확인하고 싶다면 배열입니다.

type( x ) == type( [] )

문자열 확인 :

type( x ) == type( '' ) or type( x ) == type( u'' )

없음을 확인하려면 다음을 사용하십시오.

x is None

응? 왜 일반적으로 나쁜 생각입니까? str과 unicode라는 두 가지 유형의 문자열이 있기 때문에 문자열 (3.0 이전의 경우)에 대해서만 나쁜 생각입니다. 배열의 경우 좋은 생각입니다.
hasen

@ hasen : 전반적으로 나쁜 생각입니다. 배열처럼 동작하지만 데이터베이스에서 값을 가져 오는 고유 한 유형을 정의하면 어떻게됩니까? 아무 이유없이 내 유형으로 코드가 실패합니다.
nosklo

@hasen : 링크 읽어 canonical.org/~kragen/isinstance 대부분이 투표 한 (+7) 대답, voltronw에 의한의를
nosklo

1
글쎄, 유형을 확인하는 전체 이유 (최소한)는 정확히 다른 유형 (배열을 모방하는 유형 포함)과 다르게 배열을 다루고 싶어하기 때문입니다.
hasen

2
네가 틀렸어. 구체적인 예를 들어 보겠습니다. django에는 문자열 또는 문자열 배열을 사용할 수있는 템플릿 렌더링 바로 가기가 있습니다. 이제 문자열과 배열 (목록)을 반복 할 수 있지만이 경우 함수를 구분해야합니다.
hasen

2

나는 이것이해야한다고 생각

if isinstance(obj, str)

2

특정 클래스에서는 유형이 작동하지 않습니다. 객체 유형이 확실하지 않은 경우 다음 __class__과 같이 메소드를 사용하십시오 .

>>>obj = 'a string'
>>>obj.__class__ == str
True

이 기사도 참조하십시오-http: //www.siafoo.net/article/56


2

유형을 얻으려면 다음 __class__과 같이 멤버를 사용하십시오 .unknown_thing.__class__

오리 타이핑에 대한 이야기는 여기서는 완전히 좋은 질문에 답하지 않기 때문에 쓸모가 없습니다. 내 응용 프로그램 코드에서 나는 무언가의 유형을 알 필요가 없지만 객체의 유형을 배우는 방법을 갖는 것이 여전히 유용합니다. 때로는 단위 테스트의 유효성을 검사하기 위해 실제 클래스를 가져와야합니다. 가능한 모든 객체가 동일한 API를 갖지만 하나만 정확하기 때문에 오리 타이핑이 방해가됩니다. 또한 때로는 다른 사람의 코드를 유지 관리하고 있으며 어떤 종류의 객체가 전달되었는지 전혀 모릅니다. 이것은 파이썬과 같이 동적으로 유형이 지정된 언어의 가장 큰 문제입니다. 버전 1은 개발이 매우 쉽고 빠릅니다. 버전 2는 특히 버전 1을 작성하지 않은 경우 롤빵의 고통입니다. 따라서 때로는 작성하지 않은 함수로 작업 할 때 매개 변수의 유형을 알아야합니다.

그것이 __class__매개 변수가 유용한 곳입니다. (내가 말할 수있는 한) 객체의 유형을 얻는 가장 좋은 방법 (아마도 유일한 방법)입니다.


2

사용하십시오 isinstance(object, type). 위와 같이 올바른 것을 알고 있으면 사용하기 쉽습니다 type.

isinstance('dog', str) ## gives bool True

그러나 좀 난해한 대상의 경우 사용하기가 어려울 수 있습니다. 예를 들면 다음과 같습니다.

import numpy as np 
a = np.array([1,2,3]) 
isinstance(a,np.array) ## breaks

그러나이 트릭을 수행 할 수 있습니다 :

y = type(np.array([1]))
isinstance(a,y) ## gives bool True 

따라서 y확인하려는 객체 유형 (예 :)으로 변수 ( 이 경우)를 인스턴스화 한 type(np.array())다음을 사용하는 것이 isinstance좋습니다.


0

체크 레벨에 대한 클래스를 비교할 수 있습니다.

#!/usr/bin/env python
#coding:utf8

class A(object):
    def t(self):
        print 'A'
    def r(self):
        print 'rA',
        self.t()

class B(A):
    def t(self):
        print 'B'

class C(A):
    def t(self):
        print 'C'

class D(B, C):
    def t(self):
        print 'D',
        super(D, self).t()

class E(C, B):
    pass

d = D()
d.t()
d.r()

e = E()
e.t()
e.r()

print isinstance(e, D) # False
print isinstance(e, E) # True
print isinstance(e, C) # True
print isinstance(e, B) # True
print isinstance(e, (A,)) # True
print e.__class__ >= A, #False
print e.__class__ <= C, #False
print e.__class__ <  E, #False
print e.__class__ <= E  #True
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.