Как я могу проверить тип переменных в Python?

У меня есть функция Python, которая принимает числовой аргумент, который должен быть целым, чтобы он вел себя корректно. Каков предпочтительный способ проверки этого в Python?

Моя первая реакция – сделать что-то вроде этого:

def isInteger(n): return int(n) == n 

Но я не могу не думать о том, что это 1) дорогой 2) уродливый и 3) с учетом нежных милостей машинного эпсилона.

Предоставляет ли Python какие-либо собственные средства переменных проверки типов? Или это считается нарушением динамически типизированного дизайна языка?

EDIT: так как многие люди спрашивали – приложение, о котором идет речь, работает с префиксами IPv4, используя данные из текстовых файлов. Если какой-либо ввод анализируется в float, эта запись должна рассматриваться как некорректная и игнорируемая.

8 Solutions collect form web for “Как я могу проверить тип переменных в Python?”

 isinstance(n, int) 

Если вам нужно знать, является ли это определенным фактическим int, а не подклассом int (обычно вам не нужно это делать):

 type(n) is int 

это:

 return int(n) == n 

не такая хорошая идея, как сопоставление между типами может быть правдой – особенно int(3.0)==3.0

Да, как сказал Эван, не набирайте чек. Просто попробуйте использовать значение:

 def myintfunction(value): """ Please pass an integer """ return 2 + value 

Это не имеет typecheck. Это намного лучше! Посмотрим, что произойдет, когда я попробую:

 >>> myintfunction(5) 7 

Это работает, потому что это целое число. Гектометр Попробуем текст.

 >>> myintfunction('text') Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 3, in myintfunction TypeError: unsupported operand type(s) for +: 'int' and 'str' 

Он показывает ошибку, TypeError, что и должно делать в любом случае. Если вызывающий абонент хочет поймать это, это возможно.

Что бы вы сделали, если бы вы сделали проверку типа? Сообщить об ошибке Таким образом, вам не нужно проверять тип, потому что ошибка уже появляется автоматически.

Плюс, так как вы не проверили typecheck, у вас есть функция, работающая с другими типами:

Плавает:

 >>> print myintfunction(2.2) 4.2 

Комплексные числа:

 >>> print myintfunction(5j) (2+5j) 

Десятичные:

 >>> import decimal >>> myintfunction(decimal.Decimal('15')) Decimal("17") 

Даже полностью произвольные объекты, которые могут добавлять числа!

 >>> class MyAdderClass(object): ... def __radd__(self, value): ... print 'got some value: ', value ... return 25 ... >>> m = MyAdderClass() >>> print myintfunction(m) got some value: 2 25 

Таким образом, вы явно ничего не получаете путем проверки типов. И потерять много.


ОБНОВИТЬ:

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

В этом случае я все же думаю, что вы должны передать параметр, полученный в функцию восходящего потока. Функция восходящего потока будет правильно работать с ней, например, при возникновении ошибки. Я очень сомневаюсь, что ваша функция, которая имеет дело с IP-адресами, будет вести себя странно, если вы передадите ей float. Если вы можете дать нам имя библиотеки, мы можем проверить это для вас.

Но … Если функция восходящего потока будет вести себя некорректно и убьет некоторых детей, если вы передадите ей float (я все еще очень сомневаюсь в этом), тогда просто просто вызовите int() на нем:

 def myintfunction(value): """ Please pass an integer """ return upstreamfunction(int(value)) 

Вы по-прежнему не проверяете typechecking, поэтому получаете больше преимуществ от проверки типов.


Если даже после всего этого вы действительно хотите напечатать чек, несмотря на то, что он уменьшает читаемость и производительность вашего приложения без какой-либо выгоды, используйте assert чтобы сделать это.

 assert isinstance(...) assert type() is xxxx 

Таким образом, мы можем отключить assert s и удалить эту функцию </sarcasm> из программы, вызвав ее как

 python -OO program.py 
 if type(n) is int 

Это проверяет, является ли n Python int и только int. Он не будет принимать подклассы int .

Проверка типов, однако, не соответствует «Python way». Вам лучше использовать n как int, и если он выдает исключение, поймайте его и действуйте по нему.

Python теперь поддерживает постепенную типизацию через модуль ввода и mypy . Модуль typing является частью stdlib на языке Python 3.5 и может быть загружен из PyPi, если вам нужны резервные копии для Python 2 или предыдущей версии Python 3. Вы можете установить mypy , запустив pip install mypy из командной строки.

Короче говоря, если вы хотите проверить, что какая-то функция принимает в int, float и возвращает строку, вы бы аннотировали вашу функцию следующим образом:

 def foo(param1: int, param2: float) -> str: return "testing {0} {1}".format(param1, param2) 

Если ваш файл был назван test.py , тогда вы можете проверить тип после того, как вы установили mypy, запустив mypy test.py из командной строки.

Если вы используете более старую версию Python без поддержки аннотаций функций, вы можете использовать комментарии типа для достижения того же эффекта:

 def foo(param1, param2): # type: (int, float) -> str return "testing {0} {1}".format(param1, param2) 

Вы используете ту же команду mypy test.py для файлов Python 3 и mypy --py2 test.py для файлов Python 2.

Аннотации типа полностью игнорируются интерпретатором Python во время выполнения, поэтому они налагают минимальные накладные расходы – обычный рабочий процесс заключается в том, чтобы работать с вашим кодом и периодически запускать mypy, чтобы обнаруживать ошибки и ошибки. Некоторые IDE, такие как PyCharm, будут понимать подсказки типов и могут предупреждать вас о проблемах и вводить несоответствия в вашем коде во время прямого редактирования.

Если по какой-то причине вам нужны типы, подлежащие проверке во время выполнения (возможно, вам нужно проверить много ввода?), Вы должны следовать рекомендациям, перечисленным в других ответах – например, использовать isinstance , issubclass и т. П. Существуют также некоторые библиотеки, такие как принудительное выполнение попыток выполнить проверку типов (с учетом аннотаций типа) во время выполнения, хотя я не уверен, насколько они готовы к производству на момент написания.

Для получения дополнительной информации и информации см. Сайт mypy, FAQ по mypy и PEP 484 .

Не вводите чек. Весь смысл утиной печати – это то, что вам не нужно. Например, что, если кто-то сделал что-то вроде этого:

 class MyInt(int): # ... extra stuff ... 

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

Из интерактивной командной строки вы можете запустить инструкцию типа:

 int('sometext') 

Это вызовет ошибку – ipython говорит мне:

 <type 'exceptions.ValueError'>: invalid literal for int() with base 10: 'sometext' 

Теперь вы можете написать код:

 try: int(myvar) + 50 except ValueError: print "Not a number" 

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

Я был бы склонен к чему-то вроде:

 def check_and_convert(x): x = int(x) assert 0 <= x <= 255, "must be between 0 and 255 (inclusive)" return x class IPv4(object): """IPv4 CIDR prefixes is ABCD/E where AD are integers in the range 0-255, and E is an int in the range 0-32.""" def __init__(self, a, b, c, d, e=0): self.a = check_and_convert(a) self.b = check_and_convert(a) self.c = check_and_convert(a) self.d = check_and_convert(a) assert 0 <= x <= 32, "must be between 0 and 32 (inclusive)" self.e = int(e) 

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

как насчет:

 def ip(string): subs = string.split('.') if len(subs) != 4: raise ValueError("incorrect input") out = tuple(int(v) for v in subs if 0 <= int(v) <= 255) if len(out) != 4: raise ValueError("incorrect input") return out 

Конечно, существует стандартная функция isststance (3, int) …

Python - лучший язык программирования в мире.