[python] 파이썬에서 유형을 확인하는 정식 방법은 무엇입니까?

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

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



답변

o의 인스턴스 str또는 하위 클래스인지 확인하려면 isinstance를str 사용 하십시오 ( “정식”방식 임).

if isinstance(o, str):

유형 o이 정확한지 확인하려면 str(하위 클래스 제외) :

if type(o) is str:

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

if issubclass(type(o), str):

참조 – 내장의 기능을 관련 정보는 파이썬 라이브러리 참조에.

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

if isinstance(o, basestring):

이것은 또한 유니 코드 문자열을 잡을 것입니다 (때문에 unicode의 서브 클래스가 아닌 str, 모두 strunicode의 서브 클래스 basestring). 참고 basestring더 이상 거기에 파이썬 3에 존재하는 엄격한 분리 문자열 ( str)와 바이너리 데이터 ( bytes).

또는 isinstance튜플 클래스를 허용합니다. 다음 중 하나의 하위 클래스의 인스턴스 인 True경우 이를 반환 합니다 .o(str, unicode)

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


답변

대부분의 객체의 유형을 확인하는 파이썬 방법은 그것을 확인하지 …입니다.

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

물론,이 멋진 추상화는 때때로 분해되어 isinstance(obj, cls)필요한 것입니다. 그러나 드물게 사용하십시오.


답변

isinstance(o, str)반환 할 True경우 ostr또는 상속에서 유형이다 str.

type(o) is strstr 인 True경우에만 반환 됩니다 o. 에서 상속되는 유형 인 False경우 반환 됩니다 .ostr


답변

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

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유형 이어야 하거나 반복 가능한 것입니까?).

명시 적 유형 검사의 단점은 더 일찍 오류를 포착하고 덕 타이핑보다 명확한 오류 메시지를 표시 할 수 있다는 것입니다. 오리 유형의 정확한 요구 사항은 외부 문서로만 표현할 수 있으며 (완전하고 정확해야 함) 호환되지 않는 유형의 오류는 원래 위치와는 거리가 멀어 질 수 있습니다.

파이썬의 타입 힌트는 타입을 지정하고 확인할 수 있지만 일반적인 코드 실행 중에 추가 비용이 들지 않는 절충안을 제공하기위한 것입니다.

typing타입 힌트에서 사용할 수있는 패키지 이벤트 유형 변수는 특정 유형을 필요로하지 않고 필요한 행동을 표현한다. 예를 들어, 이러한 동작과 함께 모든 유형의 필요성을 지정하는 힌트 Iterable와 같은 변수가 포함됩니다 Callable.

타입 힌트는 타입을 확인하는 가장 파이썬적인 방법이지만, 타입을 전혀 확인하지 않고 오리 타이핑에 의존하는 것이 더 파이썬적인 경우가 많습니다. 유형 힌트는 비교적 새롭고 배심원은 가장 파이썬적인 솔루션 일 때 여전히 사용 중입니다. 비교적 논쟁의 여지가 없지만 매우 일반적인 비교 : 유형 힌트는 시행 할 수있는 문서 형식을 제공하며, 코드를 조기에 생성하고 오류를 이해하기 쉽게 만들 수 있으며, 오리 입력으로 할 수없는 오류를 포착 할 수 있으며, 비정상적으로 정적 인 검사가 가능합니다 감각이지만 여전히 런타임 외부에 있습니다.) 다른 한편으로, 오리 타이핑은 오랫동안 파이썬 방식이었으며 정적 타이핑의인지 오버 헤드를 부과하지 않으며 덜 장황하며 모든 실행 가능한 유형과 일부를 허용합니다.


답변

언제 오리 타이핑이 위험한지 알지 못하고 악한 이유는 다음과 같습니다. 예를 들면 다음과 같습니다. Python 코드 (적절한 들여 쓰기를 생략 할 수 있음)는 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() 을 반환하는 웹에서 데이터를 가져올 때 이것을 많이 사용했습니다 . 이것은 실제 파일 과 동일한 방법을 구현하기 때문에 파일에서 읽는 거의 모든 방법으로 전달 될 수 있습니다 .read()

그러나을 사용할 시간과 장소가 있다고 확신합니다 isinstance(). 그렇지 않으면 아마도 없을 것입니다 🙂