문제

주어진 객체가 주어진 유형인지 확인하는 가장 좋은 방법은 무엇입니까? 객체가 주어진 유형에서 상속되는지 확인하는 것은 어떻습니까?

내가 물체가 있다고 가정 해 봅시다 o. 그것이 a인지 어떻게 확인합니까? str?

도움이 되었습니까?

해결책

확인하려면 o 인스턴스입니다 str 또는 모든 서브 클래스 str, 사용 isinstance (이것은 "표준"방식 일 것입니다) :

if isinstance(o, str):

유형이 있는지 확인합니다 o 정확히 str (서브 클래스 제외) :

if type(o) is str:

다음은 또한 작동하며 경우에 따라 유용 할 수 있습니다.

if issubclass(type(o), str):

보다 내장 기능 관련 정보에 대한 Python 라이브러리 참조.

한 가지 더 참고 :이 경우 Python 2를 사용하는 경우 실제로 사용하고 싶을 수도 있습니다.

if isinstance(o, basestring):

이것은 또한 유니 코드 문자열을 잡을 것이기 때문에 (unicode 서브 클래스가 아닙니다 str; 둘 다 str 그리고 unicode 서브 클래스입니다 basestring). 주목하십시오 basestring Python 3에는 더 이상 존재하지 않습니다. 엄격한 분리 줄의str) 및 이진 데이터 (bytes).

대안 적으로, isinstance 튜플 클래스를 수락합니다. X가 (str, unicode)의 하위 클래스의 인스턴스 인 경우 true를 반환합니다.

if isinstance(o, (str, unicode)):

다른 팁

그만큼 대부분 객체의 유형을 점검하는 Pythonic 방법은 ... 확인하지 마십시오.

파이썬이 장려되기 때문에 오리 타이핑, 당신은 그냥해야합니다 try...except 객체의 메소드를 사용하려는 방식으로 사용하려면 사용합니다. 따라서 기능이 쓰기 가능한 파일 개체를 찾고 있다면 ~하지 않다 서브 클래스인지 확인하십시오 file, 그냥 사용하려고 노력하십시오 .write() 방법!

물론 때로는 이러한 멋진 추상화가 무너지고 isinstance(obj, cls) 당신이 필요로하는 것입니다. 그러나 드물게 사용하십시오.

isinstance(o, str) 돌아올 것입니다 True 만약에 o 이다 str 또는 상속하는 유형입니다 str.

type(o) is str 돌아올 것입니다 True 경우에만 o str입니다. 돌아올 것입니다 False 만약에 o 상속하는 유형입니다 str.

질문이 질문하고 대답 한 후 유형 힌트가 Python에 추가되었습니다. 파이썬에서 힌트 유형은 유형을 확인할 수 있지만 정적으로 입력 한 언어와는 매우 다른 방식으로 확인할 수 있습니다. Python의 유형 힌트는 예상되는 인수 유형을 함수와 관련하여 기능과 관련된 런타임 액세스 할 수있는 데이터와 연결합니다. 허용 유형을 확인하려면. 유형 힌트 구문의 예 :

def foo(i: int):
    return i

foo(5)
foo('oops')

이 경우 우리는 오류가 트리거되기를 원합니다. foo('oops') 주석이 달린 유형의 인수이기 때문에 int. 추가 된 유형 힌트는 그렇지 않습니다 원인 스크립트가 정상적으로 실행될 때 오류가 발생합니다. 그러나 다른 프로그램이 쿼리하고 유형 오류를 확인하는 데 사용할 수있는 예상 유형을 설명하는 기능에 속성이 추가됩니다.

유형 오류를 찾는 데 사용할 수있는 다른 프로그램 중 하나는 다음과 같습니다. mypy:

mypy script.py
script.py:12: error: Argument 1 to "foo" has incompatible type "str"; expected "int"

(설치해야 할 수도 있습니다 mypy 패키지 관리자로부터. 나는 그것이 Cpython과 함께 제공되지 않는다고 생각하지만 어느 정도의 "공식"을 가지고있는 것 같습니다.)

이 방법으로 유형 확인은 정적으로 입력 한 컴파일 된 언어에서 유형 확인과 다릅니다. 유형은 파이썬에서 동적이기 때문에 런타임에 유형 확인을 수행해야합니다. 이는 매번 기회마다 발생한다고 주장하는 경우 올바른 프로그램에서도 비용을 부과합니다. 명시 적 유형 검사는 또한 필요한 것보다 더 제한적이며 불필요한 오류를 유발할 수 있습니다 (예 : 논증은 실제로 정확히 필요합니다. list 유형이거나 반복 할 수있는 것이 충분합니까?).

명시 적 유형 확인의 상승은 오류를 일찍 잡을 수 있고 오리 타이핑보다 더 명확한 오류 메시지를 줄 수 있다는 것입니다. 오리 유형의 정확한 요구 사항은 외부 문서로만 표현할 수 있으며 (철저하고 정확합니다) 호환되지 않는 유형의 오류는 출발 한 위치에서 멀리 떨어져있을 수 있습니다.

Python의 유형 힌트는 유형을 지정하고 확인할 수있는 타협을 제공하지만 일반적인 코드 실행 중에 추가 비용은 없습니다.

그만큼 typing 패키지는 특정 유형을 필요로하지 않고 필요한 동작을 표현하기 위해 유형 힌트로 사용할 수있는 유형 변수를 제공합니다. 예를 들어, 여기에는 다음과 같은 변수가 포함됩니다 Iterable 그리고 Callable 힌트가 해당 동작으로 모든 유형의 필요성을 지정합니다.

유형 힌트는 유형을 점검하는 가장 피스닉 방법이지만, 유형을 전혀 확인하지 않고 오리 타이핑에 의존하는 것이 훨씬 더 많은 파이닉입니다. 유형 힌트는 상대적으로 새롭고 배심원이 가장 피스닉 솔루션 일 때 여전히 배심원이 있습니다. 상대적으로 논란의 여지가 있지만 매우 일반적인 비교 : 유형 힌트는 시행 할 수있는 문서 형식을 제공하고, 코드가 더 일찍 그리고 더 쉽게 이해하기 쉽고, 오류를 이해하기 쉽고, 오리 타이핑이 할 수없는 오류를 잡을 수 있으며 (비정상적으로 점검 할 수 있습니다) 감각적이지만 여전히 런타임 외부입니다). 반면에, 오리 타이핑은 오랫동안 Pythonic 방식이었고, 정적 타이핑의인지 적 오버 헤드를 부과하지 않으며, 장점이 적으며, 모든 실행 가능한 유형과 일부를 받아 들일 것입니다.

다음은 오리 타이핑이 위험한시기를 모르고 악한 이유입니다. 예를 들어 : 여기에 파이썬 코드 (아마도 적절한 들여 쓰기를 생략 할 수 있음)는 다음과 같습니다.이 상황은 isinstance와 issubclassof 기능을 돌보면 피할 수 있습니다.

class Bomb:
    def __init__(self):
        ""

    def talk(self):
        self.explode()

    def explode(self):
        print "BOOM!, The bomb explodes."

class Duck:
    def __init__(self):
        ""
    def talk(self):
        print "I am a duck, I will not blow up if you ask me to talk."    

class Kid:
    kids_duck = None

    def __init__(self):
        print "Kid comes around a corner and asks you for money so he could buy a duck."

    def takeDuck(self, duck):
        self.kids_duck = duck
        print "The kid accepts the duck, and happily skips along"

    def doYourThing(self):
        print "The kid tries to get the duck to talk"
        self.kids_duck.talk()

myKid = Kid()
myBomb = Bomb()
myKid.takeDuck(myBomb)
myKid.doYourThing()
isinstance(o, str)

문서에 링크

파이썬과 같은 역동적 인 언어를 사용하는 것에 대한 멋진 점은 실제로 그런 것을 확인할 필요가 없다는 것입니다.

나는 단지 당신의 객체에 필요한 방법을 호출하고 AttributeError. 나중에이를 통해 테스트를위한 개체를 조롱하는 것과 같은 다른 작업을 수행하기 위해 다른 (겉보기에는 관련이없는) 객체로 메소드를 호출 할 수 있습니다.

웹에서 데이터를 가져올 때 이것을 많이 사용했습니다. urllib2.urlopen() 반환 a 파일 좋아요 물체. 이것은 파일에서 읽는 거의 모든 메소드로 전달 될 수 있습니다. read() 실제 파일로서의 방법.

그러나 나는 사용할 시간과 장소가 있다고 확신합니다 isinstance(), 그렇지 않으면 아마 거기에 없을 것입니다 :)

휴고에게 :

당신은 아마도 의미합니다 list 보다는 array, 그러나 그것은 유형 확인의 전체 문제를 가리 킵니다. 해당 객체가 목록인지 알고 싶지 않습니다. 어떤 종류의 시퀀스인지 또는 단일 객체인지 알고 싶습니다. 따라서 시퀀스처럼 사용하십시오.

객체를 기존 시퀀스에 추가하거나 일련의 객체 인 경우 모두 추가하십시오.

try:
   my_sequence.extend(o)
except TypeError:
  my_sequence.append(o)

이것의 한 가지 요령은 문자열 및/또는 문자열 시퀀스로 작업하는 경우입니다. 문자열은 종종 단일 객체로 생각되지만 일련의 문자이기도합니다. 그보다 더 나쁘게, 그것은 실제로 일련의 단일 길이 스트링 시퀀스이기 때문에.

나는 보통 API를 설계하여 단일 값이나 시퀀스 만 허용되도록 선택합니다. 넣기가 어렵지 않습니다 [ ] 필요한 경우 전달할 때 단일 값 주위.

(이것은 현악기에 오류가 발생할 수 있지만, 시퀀스처럼 보이기 때문에.)

더 복잡한 유형의 검증을 위해 TypeGuard파이썬 유형 힌트 주석을 기반으로 검증의 접근 방식 :

from typeguard import check_type
from typing import List

try:
    check_type('mylist', [1, 2], List[int])
except TypeError as e:
    print(e)

매우 깨끗하고 읽기 쉬운 방식으로 매우 복잡한 검증을 수행 할 수 있습니다.

check_type('foo', [1, 3.14], List[Union[int, float]])
# vs
isinstance(foo, list) and all(isinstance(a, (int, float)) for a in foo) 

아래 줄을 확인하여 주어진 값이 어떤 문자 유형인지 확인할 수 있습니다.

def chr_type(chrx):
    if chrx.isalpha()==True:
        return 'alpha'
    elif chrx.isdigit()==True:
        return 'numeric'
    else:
        return 'nothing'

chr_type("12)
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top