[python] 객체의 유형을 결정 하시겠습니까?

변수가 목록, 사전 또는 다른 항목인지 확인하는 간단한 방법이 있습니까? 유형이 될 수있는 객체를 다시 가져오고 차이를 말할 수 있어야합니다.



답변

객체 유형을 식별하는 데 도움이되는 내장 함수가 두 개 있습니다. 당신은 사용할 수 있습니다 type() 당신은 객체의 정확한 유형을 필요로하는 경우,과 isinstance()확인 무언가에 대한 개체의 유형입니다. 일반적으로 isistance()매우 강력하고 형식 상속도 지원하므로 대부분의 시간 을 사용하려고합니다 .


객체의 실제 유형을 얻으려면 내장 type()함수 를 사용합니다 . 객체를 유일한 매개 변수로 전달하면 해당 객체의 유형 객체가 반환됩니다.

>>> type([]) is list
True
>>> type({}) is dict
True
>>> type('') is str
True
>>> type(0) is int
True

이것은 물론 사용자 정의 유형에도 적용됩니다.

>>> class Test1 (object):
        pass
>>> class Test2 (Test1):
        pass
>>> a = Test1()
>>> b = Test2()
>>> type(a) is Test1
True
>>> type(b) is Test2
True

참고 type()개체 만의 즉각적인 유형을 반환하지만 형의 상속에 대해 얘기 할 수 없습니다.

>>> type(b) is Test1
False

이를 다루려면 isinstance함수를 사용해야합니다 . 이것은 물론 내장 유형에도 적용됩니다.

>>> isinstance(b, Test1)
True
>>> isinstance(b, Test2)
True
>>> isinstance(a, Test1)
True
>>> isinstance(a, Test2)
False
>>> isinstance([], list)
True
>>> isinstance({}, dict)
True

isinstance()파생 된 형식도 허용하므로 개체의 형식을 확인하는 데 일반적으로 선호되는 방법입니다. 따라서 실제로 어떤 이유에서든 유형 객체가 필요하지 않으면를 사용하는 isinstance()것이 좋습니다 type().

의 두 번째 매개 변수는 isinstance()튜플 유형도 허용하므로 여러 유형을 한 번에 확인할 수 있습니다. isinstance그런 다음 객체가 이러한 유형 중 하나 인 경우 true를 반환합니다.

>>> isinstance([], (tuple, list, set))
True


답변

당신은 그것을 사용하여 할 수 있습니다 type():

>>> a = []
>>> type(a)
<type 'list'>
>>> f = ()
>>> type(f)
<type 'tuple'>


답변

tryexcept블록 을 사용하는 것이 더 Pythonic 일 수 있습니다 . 이렇게하면 목록과 같은 쿼크 클래스 또는 dict와 같은 쿼크 클래스가 있으면 실제로 유형 무엇이든 관계없이 올바르게 작동합니다 .

명확히하기 위해, 변수 유형 사이의 “차이점을 구별하는”선호되는 방법은 덕 타이핑 이라는 것입니다. 되려고. 예를 들어, getattr및로 대괄호 연산자를 오버로드 setattr하지만 재미있는 내부 구성표를 사용 하는 클래스가 있으면 에뮬레이션하려는 경우 사전으로 작동하는 것이 적합합니다.

type(A) is type(B)점검의 또 다른 문제점 A은의 서브 클래스 인 경우 프로그래밍 방식 B으로 원하는 false시점으로 평가 한다는 것입니다 true. 객체가리스트의 서브 클래스 인 경우,리스트처럼 작동해야합니다. 다른 답변에 제시된 유형을 확인하면이를 방지 할 수 있습니다. ( isinstance그러나 작동합니다).


답변

객체의 인스턴스에는 다음이 있습니다.

__class__

속성. 다음은 Python 3.3 콘솔에서 가져온 샘플입니다.

>>> str = "str"
>>> str.__class__
<class 'str'>
>>> i = 2
>>> i.__class__
<class 'int'>
>>> class Test():
...     pass
...
>>> a = Test()
>>> a.__class__
<class '__main__.Test'>

python 3.x 및 New-Style 클래스 (Python 2.6에서 선택적으로 사용 가능)에서 클래스와 유형이 병합되어 예기치 않은 결과가 발생할 수 있습니다. 주로 이런 이유로 종류 / 클래스를 테스트 나의 마음에 드는 방법은이다 isinstance 기능이 내장되어 있습니다.


답변

파이썬 객체의 타입 결정

객체의 유형 결정 type

>>> obj = object()
>>> type(obj)
<class 'object'>

그것이 작동하지만, 이중 밑줄 속성 __class__은 피상적으로 공개적이지 않으며, 아마도이 경우에는 아니지만 내장 함수는 일반적으로 더 나은 동작을합니다.

>>> obj.__class__ # avoid this!
<class 'object'>

타입 검사

변수가 목록, 사전 또는 다른 항목인지 확인하는 간단한 방법이 있습니까? 유형이 될 수있는 객체를 다시 가져오고 차이를 말할 수 있어야합니다.

글쎄, 그것은 다른 질문입니다, type-use를 사용하지 마십시오 isinstance:

def foo(obj):
    """given a string with items separated by spaces,
    or a list or tuple,
    do something sensible
    """
    if isinstance(obj, str):
        obj = str.split()
    return _foo_handles_only_lists_or_tuples(obj)

여기에는 strLiskov Substitution의 원칙에 따라 사용자가 코드를 어 기지 않고 서브 클래스 인스턴스를 사용할 수 있기를 원하는 서브 클래 싱으로 사용자가 영리하거나 현명한 작업을 수행하는 경우가 포함됩니다 isinstance.

추상화 사용

더 좋은 점은 collections또는 numbers다음 에서 특정 추상 기본 클래스를 찾을 수 있습니다 .

from collections import Iterable
from numbers import Number

def bar(obj):
    """does something sensible with an iterable of numbers,
    or just one number
    """
    if isinstance(obj, Number): # make it a 1-tuple
        obj = (obj,)
    if not isinstance(obj, Iterable):
        raise TypeError('obj must be either a number or iterable of numbers')
    return _bar_sensible_with_iterable(obj)

또는 명시 적으로 유형 검사하지 마십시오

또는 아마도 무엇보다도 오리 타이핑을 사용하고 코드를 명시 적으로 유형 검사하지 마십시오. 오리 타이핑은 Liskov 대체를 더 우아하고 덜 장황하게 지원합니다.

def baz(obj):
    """given an obj, a dict (or anything with an .items method)
    do something sensible with each key-value pair
    """
    for key, value in obj.items():
        _baz_something_sensible(key, value)

결론

  • type실제로 인스턴스 클래스를 얻는 데 사용 합니다.
  • isinstance실제 서브 클래스 또는 등록 된 추상화를 명시 적으로 확인하는 데 사용 합니다.
  • 그리고 적절한 곳에서 유형 검사를 피하십시오.

답변

당신은 사용할 수 있습니다 type()또는 isinstance().

>>> type([]) is list
True

list동일한 이름의 현재 범위에서 변수를 할당하여 클로버 또는 다른 유형을 경고 할 수 있습니다 .

>>> the_d = {}
>>> t = lambda x: "aight" if type(x) is dict else "NOPE"
>>> t(the_d) 'aight'
>>> dict = "dude."
>>> t(the_d) 'NOPE'

위에서 우리 dict는 문자열에 다시 할당되는 것을 보았습니다 .

type({}) is dict

… 실패.

이 문제를 해결하고 type()보다 신중하게 사용하려면 :

>>> import __builtin__
>>> the_d = {}
>>> type({}) is dict
True
>>> dict =""
>>> type({}) is dict
False
>>> type({}) is __builtin__.dict
True


답변

질문이 꽤 오래되었지만 적절한 방법을 찾아 내면서이 문제를 우연히 발견 했으며 적어도 Python 2.x (Python 3에서는 확인하지 않았지만 고전적인 클래스에서 문제가 발생했기 때문에 여전히 명확해야 함) 그런 버전에서 사라지면 아마 중요하지 않을 것입니다).

여기서 제목의 질문에 대답하려고합니다 . 임의의 객체 유형을 어떻게 결정할 수 있습니까? isinstance를 사용하거나 사용하지 않는 것에 대한 다른 제안은 많은 의견과 답변에서 훌륭하지만 이러한 문제는 다루지 않습니다.

type()접근 방식 의 주요 문제 는 이전 스타일 인스턴스에서 제대로 작동하지 않는다는 것입니다 .

class One:
    pass

class Two:
    pass


o = One()
t = Two()

o_type = type(o)
t_type = type(t)

print "Are o and t instances of the same class?", o_type is t_type

이 스 니펫을 실행하면 다음이 생성됩니다.

Are o and t instances of the same class? True

나는 대부분의 사람들이 기대하는 것이 아니라고 주장한다.

__class__접근 방식은 정확성에 가장 가까운,하지만 하나의 중요한 경우에없는 일이됩니다 옛날 스타일의 전달 된 객체 인 경우 클래스 (!하지 인스턴스), 이러한 개체는 속성이 부족하기 때문이다.

이것은 내가 생각할 수있는 가장 작은 코드 스 니펫으로 일관성있는 질문을 일관된 방식으로 충족시킵니다.

#!/usr/bin/env python
from types import ClassType
#we adopt the null object pattern in the (unlikely) case
#that __class__ is None for some strange reason
_NO_CLASS=object()
def get_object_type(obj):
    obj_type = getattr(obj, "__class__", _NO_CLASS)
    if obj_type is not _NO_CLASS:
        return obj_type
    # AFAIK the only situation where this happens is an old-style class
    obj_type = type(obj)
    if obj_type is not ClassType:
        raise ValueError("Could not determine object '{}' type.".format(obj_type))
    return obj_type


댓글 달기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다