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

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

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

10 ответов


чтобы проверить, если 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)):

на большинство Pythonic способ проверить тип объекта... не проверить его.

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

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


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

type(o) is str вернутся true если и только если o - это НТР. Он вернется false если o имеет тип, который наследуется от str. ----


после того, как вопрос был задан и ответил:подсказки типа были добавлены в 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, но, кажется, есть некоторый уровень "officialness".)

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

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

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

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

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


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

ссылка на docs


Я думаю, что круто использовать динамический язык, такой как Python, вам действительно не нужно проверять что-то подобное.

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

Я много использовал это при получении данных из интернета с помощью urllib2.urlopen() который возвращает как


В Hugo:

вы, вероятно, имеете в виду list, а не array, но это указывает на всю проблему с проверкой типа - вы не хотите знать, является ли рассматриваемый объект списком, вы хотите знать, является ли это какой-то последовательностью или это один объект. Поэтому постарайтесь использовать это как последовательность.

скажем, вы хотите добавить объект в существующую последовательность, или если это последовательность объектов, добавьте их все

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

один трюк с этим, если вы работа со строками и / или последовательностями строк - это сложно, так как строка часто рассматривается как один объект, но это также последовательность символов. Хуже того, это действительно последовательность строк одной длины.

обычно я выбираю дизайн своего API, чтобы он принимал только одно значение или последовательность - это облегчает работу. Это не трудно поставить [ ] вокруг вашего единственного значения, когда вы передаете его, если это необходимо.

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


аннотации типа Python теперь вещь. Взгляните на mypy


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

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

chr_type("12)