함수 - Python에서 유형을 확인하는 표준 방법은 무엇입니까?




파이썬 정수인지 판별 (7)

주어진 객체가 주어진 유형인지 여부를 확인하는 가장 좋은 방법은 무엇입니까? 객체가 주어진 유형으로부터 상속 받았는지 확인하는 것은 어떻습니까?

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


Python 유형 주석이 이제는 일이되었습니다. mypymypy


객체의 유형을 검사하는 가장 Pythonic 한 방법은 ... 확인하지 않는 것입니다.

Python이 Duck Typing을 권장하기 때문에, 당신이 사용 try...except 하는 방식대로 객체의 메소드를 사용하는 try...excepttry...except 해야합니다. 따라서 함수가 쓰기 가능한 파일 객체를 찾고 있다면 파일의 서브 클래스인지 확인 하지 말고 그냥 .write() 메소드를 사용하십시오!

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


다음은 위험한시기를 모른 채 오리 입력이 악의적 인 이유입니다. 예를 들면 다음과 같습니다 : 파이썬 코드 (적절한 들여 쓰기 생략)가 있습니다.이 상황은 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()

질문을하고 대답 한 후에 유형 힌트가 파이썬에 추가되었습니다 . 파이썬에서 타입 힌트를 사용하면 타입을 검사 할 수 있지만 정적으로 타입이 지정된 언어와는 아주 다른 방식으로 검사 할 수 있습니다. 파이썬에서 타입 힌트는 예상되는 타입의 인자를 함수와 관련된 런타임 접근 가능 데이터로 함수와 연결시켜 타입을 검사 할 수있게 합니다. 유형 힌트 구문의 예 :

def foo(i: int):
    return i

foo(5)
foo('oops')

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

형식 오류를 찾는 데 사용할 수있는 이러한 다른 프로그램 중 하나는 mypy .

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

(패키지 관리자에서 mypy 를 설치해야 할 수도 있습니다. CPython에는 포함되어 있지 않지만 "공식성"이 어느 정도 있다고 생각됩니다.)

이 방식으로 유형을 검사하는 것은 정적으로 유형이 컴파일 된 언어로 유형을 검사하는 것과는 다릅니다. 유형은 파이썬에서 동적이기 때문에 유형 검사는 런타임에 완료되어야합니다. 따라서 정확한 프로그램에서도 비용이 부과됩니다. 명시 적 유형 검사는 필요 이상으로 더 제한적일 수 있으며 불필요한 오류를 일으킬 수 있습니다 (예 : 인수가 실제로 정확히 list 유형이거나 충분히 반복 가능한 항목)?

명시 적 유형 검사의 단점은 오류를 더 일찍 잡을 수 있고 오리 입력보다 명확한 오류 메시지를 줄 수 있다는 것입니다. 오리 유형의 정확한 요구 사항은 외부 문서로만 표현할 수 있습니다 (잘하면 완벽하고 정확합니다). 호환되지 않는 유형의 오류는 원래의 위치에서 멀리 떨어져 발생할 수 있습니다.

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

typing 패키지는 특정 유형을 요구하지 않고 필요한 동작을 표현하기 위해 유형 힌트에 사용할 수있는 유형 변수를 제공합니다. 예를 들어, IterableCallable 과 같은 변수는 힌트로 해당 동작이있는 모든 유형의 필요성을 지정합니다.

형식 힌트는 형식을 검사하는 가장 Pythonic 한 방법이지만 형식을 전혀 확인하지 않고 더티 입력에 의존하는 것은 훨씬 더 Pythonic입니다. 형식 힌트는 상대적으로 새롭고 배심원은 Pythonic 솔루션을 가장 많이 사용합니다. 상대적으로 논쟁의 여지가 없지만 매우 일반적인 비교 : 유형 힌트는 시행 할 수있는 문서 형식을 제공하며, 오류를 더 일찍 그리고 쉽게 이해할 수 있도록 코드를 생성하고, duck 입력이 할 수없는 오류를 잡아낼 수 있으며 정적으로 검사 할 수 있습니다 감각이지만 그것은 여전히 ​​런타임의 밖에있다). 반면에, 오리 타이핑은 오랫동안 파이썬적인 방식이었으며, 정적 타이핑의인지 오버 헤드를 부과하지 않으며, 덜 장황하고 모든 실행 가능한 유형을 수용 한 다음 일부를 수용합니다.


휴고에게 :

array 보다는 list 의미 할 수도 있지만 형식 검사와 관련된 모든 문제를 가리키고 있습니다. 문제의 대상이 목록인지, 시퀀스인지 또는 단일 항목인지 여부를 알고 싶지 않습니다. 목적. 따라서 시퀀스처럼 사용하십시오.

기존 시퀀스에 객체를 추가하고 싶거나 객체 시퀀스 인 경우 객체를 모두 추가한다고 가정 해 보겠습니다.

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

한 가지 트릭은 문자열 및 / 또는 문자열 시퀀스로 작업하는 경우입니다. 문자열은 종종 단일 개체로 간주되기 때문에 까다로운 작업이지만 문자 시퀀스이기도합니다. 그보다 더 나쁜 것은 실제로는 단일 길이 문자열입니다.

일반적으로 API를 디자인하여 단일 값이나 시퀀스 만 허용하도록 선택하기 때문에 작업이 더 쉬워집니다. 필요한 경우 전달할 때 단일 값을 [ ] 로 묶는 것은 어렵지 않습니다.

(문자열이 시퀀스처럼 보이기 때문에 문자열에 오류가 발생할 수 있습니다.)


isinstance(o, str)ostr 이거나 str 을 상속하는 유형 인 경우 true 를 반환 true .

type(o) is strtype(o) is str 경우에만 true 리턴 true . ostr 을 상속받는 타입이면 false 를 반환합니다. ----






types