Я думаю, что основной причиной этого действительно печального ограничения является тот факт, что конструкторы не могут виртуально. Вследствие этого компилятор не может сгенерировать код, который копирует объект, не зная его времени во время компиляции.
Если вас действительно раздражает использование try / except
повсюду, напишите, пожалуйста, вспомогательную функцию:
def RepresentsInt(s):
try:
int(s)
return True
except ValueError:
return False
>>> print RepresentsInt("+123")
True
>>> print RepresentsInt("10.0")
False
Это будет ПУТЬ больше кода, чтобы точно покрыть все строки что Python считает целые числа. Я говорю, просто будь питоником на этом.
Если Вы хотите принять цифры более низкого ASCII только, вот тесты, чтобы сделать так:
Python 3.7 +: (u.isdecimal() and u.isascii())
Python < = 3.6: (u.isdecimal() and u == str(int(u)))
Другие ответы предлагают использовать .isdigit()
или .isdecimal()
, но эти оба включают некоторые верхние-unicode символы такой как '٢'
(u'\u0662'
):
u = u'\u0662' # '٢'
u.isdigit() # True
u.isdecimal() # True
u.isascii() # False (Python 3.7+ only)
u == str(int(u)) # False
Я предлагаю следующее:
import ast
def is_int(s):
return isinstance(ast.literal_eval(s), int)
От эти документы :
Безопасно оценивают узел выражения или строку, содержащую литерал Python или контейнерный дисплей. Строка или обеспеченный узел могут только состоять из следующих структур литерала Python: строки, байты, числа, кортежи, списки, dicts, наборы, булевские переменные и Ни один.
я должен отметить, что это повысит ValueError
исключение при вызове против чего-либо, что не составляет литерал Python. Начиная с вопроса, который задают для решения без попытки/кроме, я сделал, чтобы Kobayashi-Maru ввел решение для этого:
from ast import literal_eval
from contextlib import suppress
def is_int(s):
with suppress(ValueError):
return isinstance(literal_eval(s), int)
return False
ВЇ \_ (гѓ „) _/ВЇ
Я использую этого:
all([xi in '1234567890' for xi in x])
Это не размещает отрицательные числа, таким образом, Вы могли использовать:
all([xi in '1234567890-' for xi in x])
Вы могли также передать x ул. (), если Вы не уверены, что вход является строкой:
all([xi in '1234567890-' for xi in str(x)])
существуют по крайней мере два (край?) случаи, где это разваливается:
type(1E3)
в интерпретатор, Вы доберетесь <class 'float'>
, Таким образом, он не будет работать на каждый возможный вход, но если можно исключить те возможности, это - OK короткая проверка, которая возвращается False
, если x не является целым числом. Я не знаю, является ли это pythonic, но это - одна строка, и относительно ясно, что делает код.
В подходе Грега Хьюгилла не хватало нескольких компонентов: ведущего символа «^» для соответствия только началу строки и составление re заранее. Но этот подход позволит вам избежать попытки: exept:
import re
INT_RE = re.compile(r"^[-]?\d+$")
def RepresentsInt(s):
return INT_RE.match(str(s)) is not None
Мне было бы интересно, почему вы пытаетесь избежать попытки: except?
Используйте регулярное выражение:
import re
def RepresentsInt(s):
return re.match(r"[-+]?\d+$", s) is not None
Если вы также должны принимать десятичные дроби:
def RepresentsInt(s):
return re.match(r"[-+]?\d+(\.0*)?$", s) is not None
Для повышения производительности, если вы делаете это часто, скомпилируйте регулярное выражение только один раз, используя re.compile ()
.
с положительными целыми числами вы можете использовать .isdigit
:
>>> '16'.isdigit()
True
он не работает с отрицательными целыми числами. предположим, вы можете попробовать следующее:
>>> s = '-17'
>>> s.startswith('-') and s[1:].isdigit()
True
он не будет работать с форматом '16 .0 '
, который в этом смысле аналогичен приведению int
.
edit :
def check_int(s):
if s[0] in ('-', '+'):
return s[1:].isdigit()
return s.isdigit()