проверка - Каков канонический способ проверки типа в Python?




type int python (6)

Каков наилучший способ проверить, является ли данный объект заданным типом? Как насчет проверки того, наследует объект от данного типа?

Предположим, у меня есть объект o . Как проверить, является ли это str ?


Вот пример, почему печатание утки - зло, не зная, когда это опасно. Например: Вот код 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()

Вы можете проверить строку ниже, чтобы проверить, какой тип символа задан:

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

chr_type("12)

После того, как был задан вопрос и ответили, в Python были добавлены подсказки типа . Тип подсказок в 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, но, похоже, имеет определенный уровень «официальности».)

Тип проверки таким образом отличается от проверки типов в статически типизированных скомпилированных языках. Поскольку типы являются динамическими в Python, проверка типов должна выполняться во время выполнения, что накладывает затраты - даже на правильные программы - если мы настаиваем на том, чтобы это происходило во всех случаях. Явные проверки типов также могут быть более строгими, чем это необходимо, и вызывать ненужные ошибки (например, действительно ли аргумент должен иметь точно тип list или что-либо итерабельнее достаточно?).

Поверхность явной проверки типов заключается в том, что она может ловить ошибки раньше и давать более четкие сообщения об ошибках, чем утиная печать. Точные требования к типу утки могут быть выражены только с помощью внешней документации (надеюсь, что она будет тщательной и точной), а ошибки от несовместимых типов могут происходить далеко от того места, откуда они происходят.

Подсказки типа Python предназначены для компрометации, где типы могут быть указаны и проверены, но при обычном выполнении кода нет дополнительных затрат.

Пакет typing предлагает переменные типа, которые могут использоваться в подсказках типа для выражения необходимого поведения без необходимости использования определенных типов. Например, он включает переменные, такие как Iterable и Callable для подсказок, чтобы указать необходимость любого типа с этими поведением.

Хотя подсказки типов - это самый Pythonic способ проверить типы, часто даже больше Pythonic не проверять типы вообще и полагаться на печатание утки. Типовые намеки относительно новы, и жюри все еще не работает, когда они являются самым питоническим решением. Сравнительно непротиворечивое, но очень общее сравнение: подсказки типов предоставляют форму документации, которая может быть применена, позволяет генерировать код раньше и легче понять ошибки, может ловить ошибки, которые печатают утки, и их можно проверять статически (в необычном но он все еще находится вне среды исполнения). С другой стороны, утиная типизация была путинским способом в течение длительного времени, не налагала когнитивных накладных расходов на статическую типизацию, была менее многословной и принимала все жизнеспособные типы, а затем некоторые.


Чтобы проверить, является ли 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 ( unicode не является подклассом str а str и unicode являются подклассами basestring ). Обратите внимание, что basestring больше не существует в python 3, где существует строгое разделение строк ( str ) и двоичных данных ( bytes ).

Альтернативно, isinstance принимает кортеж классов. Это вернет True, если x является экземпляром любого подкласса любого из (str, unicode):

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

isinstance(o, str) вернет true если o является str или имеет тип, который наследуется от str .

type(o) is str , вернет true тогда и только тогда, когда o является str. Он вернет false если o имеет тип, наследующий от str . ----


Самый Pythonic способ проверить тип объекта ... не проверять его.

Поскольку Python поощряет Duck Typing , вы должны просто try...except чтобы использовать методы объекта так, как вы хотите их использовать. Поэтому, если ваша функция ищет записываемый объект, не проверяйте, что это подкласс file , просто попробуйте использовать его .write() !

Конечно, иногда эти красивые абстракции ломаются, и isinstance(obj, cls) - это то, что вам нужно. Но используйте экономно.





types