itsource

오브젝트 타입을 결정하시겠습니까?

mycopycode 2022. 9. 23. 00:18
반응형

오브젝트 타입을 결정하시겠습니까?

변수가 목록인지, 사전인지 또는 다른 것인지 확인하는 간단한 방법이 있습니까?

오브젝트 유형을 식별하는 데 도움이 되는 두 가지 기능이 내장되어 있습니다.정확한 개체 유형이 필요한 경우 및 개체 유형을 무언가에 대해 확인하는 데 사용할 수 있습니다.보통 사용하는 것은isinstance()매우 견고하고 유형 상속도 지원하므로 대부분의 경우 그렇습니다.


개체의 실제 유형을 가져오려면 기본 제공 함수를 사용합니다.개체를 유일한 매개 변수로 전달하면 해당 개체의 유형 개체가 반환됩니다.

>>> 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(b, Test1)
True
>>> isinstance(b, Test2)
True
>>> isinstance(a, Test1)
True
>>> isinstance(a, Test2)
False
>>> isinstance([], list)
True
>>> isinstance({}, dict)
True

isinstance()는 파생된 유형도 받아들이기 때문에 일반적으로 개체 유형을 확인하는 데 선호되는 방법입니다. (로든) type object가 한 경우를 하고 type을 합니다.isinstance()type().

의 두 .isinstance()여러 종류의 타입을 사용할 수 있기 때문에 여러 타입을 동시에 확인할 수 있습니다. isinstance오브젝트가 다음 유형 중 하나일 경우 true가 반환됩니다.

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

type():

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

피톤어를 이 더 수.tryexcept그러면 리스트처럼 꽥꽥거리는 수업이나 받아쓰기처럼 꽥꽥거리는 수업이 있으면 그 수업의 종류와 상관없이 올바르게 동작하게 됩니다.

명확하게 하기 위해 변수 유형 간의 "차이"를 구분하는 방법은 duck typing이라고 불리는 방법을 사용하는 것입니다. 변수가 응답하는 메서드(및 반환 유형)가 서브루틴에서 기대하는 방식인 한 원하는 대로 처리하십시오.예를 들어, 괄호 연산자를 오버로드하는 클래스가 있는 경우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에서 사용 가능)에서는 클래스와 유형이 병합되어 예기치 않은 결과가 발생할 수 있습니다.이 때문에, 타입/클래스를 테스트하기 위해서 가장 좋아하는 방법은, 짜넣기 기능에 의한 것입니다.

Python 개체 유형 결정

다음을 사용하여 개체 유형을 결정합니다.type

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

동작하지만 다음과 같은 이중 언더스코어 속성은 피하십시오.__class__- 의미론적으로는 공개되지 않으며, 이 경우에는 아닐 수도 있지만, 일반적으로 내장된 함수가 더 나은 동작을 합니다.

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

활자 검사

변수가 목록인지, 사전인지 또는 다른 것인지 확인하는 간단한 방법이 있습니까?어떤 타입인지 알 수 있는 오브젝트를 돌려받았는데, 차이를 알 수 있어야 합니다.

그건 또 다른 질문입니다.활자를 사용하지 마세요.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)

이곳에서 사용자 이는 사용자가 서브클래싱을 통해 영리하거나 합리적인 행동을 하고 있는 경우를 대상으로 합니다 subclassing가 무언가를 clever이나 합리적인 할 수 있는 경우에나 들어맞는다str-Liskov 대체의 원칙에 따라 코드를 깨지 않고 서브 클래스 인스턴스를 사용할 수 있도록--Liskov 대체 원칙에 따라 코드를 깨지 않고 서브클래스 인스턴스를 사용할 수 있어야 합니다고 싶다.isinstance이것을 지지해.A이를 지원합니다.

추상화 사용

심지어 잘, 당신은 특정한 추상 기본 클래스에더 좋은 방법은 다음에서 특정 추상 기본 클래스를 찾을 수 있습니다 보일지 몰라도.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)

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

또는 duck-typing을 사용하여 코드를 명시적으로 검사하지 않는 것이 좋습니다.덕 타이핑은 더 우아하고 덜 장황한 리스코프 대체 기능을 지원합니다.

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

임기응변으로 조심하다

isinstance(True, bool)
True
>>> isinstance(True, int)
True

하지만 타이프

type(True) == bool
True
>>> type(True) == int
False

질문들이 꽤 오래되었지만, 제가 적절한 방법을 찾다가 우연히 발견하게 되었고, 적어도 Python 2.x에 대해서는 아직 명확하게 할 필요가 있다고 생각합니다(Python 3.x에서는 체크하지 않았지만, 이러한 버전의 클래식 클래스에서 문제가 발생하고 있기 때문에, 아마 문제가 되지 않을 것입니다).

여기서 저는 제목의 질문에 답하려고 합니다: 임의 객체의 유형을 어떻게 결정할 수 있습니까?instance 사용 또는 사용 안 함에 대한 다른 제안들은 많은 댓글과 답변에서 괜찮지만, 저는 이러한 우려에 대처하지 않습니다.

『 』의 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__approach는 정확성에 가장 가깝지만 한 가지 중요한 경우에는 작동하지 않습니다. 즉, 전달된 객체가 오래된 스타일의 클래스(인스턴스가 아님!)인 경우, 이러한 객체에 이러한 속성이 없기 때문입니다.

이것은 내가 생각할 수 있는 가장 작은 코드 조각이며, 일관된 방식으로 그러한 정당한 질문을 충족시킨다.

#!/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

앞서 말한 답변과는 별도로, 오리타입을 보완하는 추상 기본 클래스(ABC)가 몇 가지 포함되어 있는 것을 언급할 필요가 있습니다.

예를 들어, 다음과 같은 항목이 목록인지 여부를 명시적으로 확인하는 대신,

isinstance(my_obj, list)

만약 당신이 가지고 있는 오브젝트가 아이템을 가져올 수 있는지 확인하는 것에만 관심이 있다면 다음을 사용할 수 있습니다.

from collections.abc import Sequence
isinstance(my_obj, Sequence) 

아이템의 취득, 설정, 삭제를 가능하게 하는 오브젝트(, 가변 시퀀스)에 엄격하게 관심이 있는 경우,collections.abc.MutableSequence.

라는 많은 ABC가 되어 있습니다.Mapping할 수 는, 「」를 참조해 주세요.Iterable,Callable, 등이러한 모든 것에 대해서는, 의 메뉴얼을 참조해 주세요.

실제적인 , '는 대신 '는을 사용합니다.type ★★★★★★★★★★★★★★★★★」isinstance또, 범용 함수(다른 타입의 같은 동작을 실장하는 복수의 함수로 이루어진 함수)를 정의하기 위해서도 사용할 수 있습니다.

즉, 다음과 같은 코드가 있는 경우에 사용하는 것이 좋습니다.

def do_something(arg):
    if isinstance(arg, int):
        ... # some code specific to processing integers
    if isinstance(arg, str):
        ... # some code specific to processing strings
    if isinstance(arg, list):
        ... # some code specific to processing lists
    ...  # etc

다음은 동작의 간단한 예를 제시하겠습니다.

from functools import singledispatch


@singledispatch
def say_type(arg):
    raise NotImplementedError(f"I don't work with {type(arg)}")


@say_type.register
def _(arg: int):
    print(f"{arg} is an integer")


@say_type.register
def _(arg: bool):
    print(f"{arg} is a boolean")
>>> say_type(0)
0 is an integer
>>> say_type(False)
False is a boolean
>>> say_type(dict())
# long error traceback ending with:
NotImplementedError: I don't work with <class 'dict'>

또한 추상 클래스를 사용하여 여러 유형을 동시에 다룰 수 있습니다.

from collections.abc import Sequence


@say_type.register
def _(arg: Sequence):
    print(f"{arg} is a sequence!")
>>> say_type([0, 1, 2])
[0, 1, 2] is a sequence!
>>> say_type((1, 2, 3))
(1, 2, 3) is a sequence!
value = 12
print(type(value)) # will return <class 'int'> (means integer)

아니면 이런 걸 할 수도 있고

value = 12
print(type(value) == int) # will return true

type() 사용

x='hello this is a string'
print(type(x))

산출량

<class 'str'>

str만 추출하려면 이것을 사용합니다.

x='this is a string'
print(type(x).__name__)#you can use__name__to find class

산출량

str

을 쓰면type(variable).__name__

type()입니다.isinstance() 히,의 경우booleans:

True ★★★★★★★★★★★★★★★★★」False는, 「」를 하는 일 뿐입니다.1 ★★★★★★★★★★★★★★★★★」0 이렇게 해서,

isinstance(True, int)

그리고.

isinstance(False, int)

다 '''를 반환한다.True은 모두 두 부란은 모두 정수의 인스턴스입니다. type() 더 영리해요.

type(True) == int

False.

일반적으로 객체에서 클래스 이름을 가진 문자열을 추출할 수 있습니다.

str_class = object.__class__.__name__

비교해서 보면

if str_class == 'dict':
    # blablabla..
elif str_class == 'customclass':
    # blebleble..

완전성을 위해 인스턴스가 아닌 서브타입의 타입 체크에는 isinstance는 기능하지 않습니다.그것이 완벽하게 말이 되지만, (인정된 것을 포함한) 어떤 대답도 그것을 다루지 않습니다.그것에는 issubclass를 사용합니다.

>>> class a(list):
...   pass
... 
>>> isinstance(a, list)
False
>>> issubclass(a, list)
True

언급URL : https://stackoverflow.com/questions/2225038/determine-the-type-of-an-object

반응형