Есть ли встроенный или более Pythonic способ попытаться разобрать строку в целое число - PullRequest
53 голосов
/ 14 февраля 2010

Мне пришлось написать следующую функцию для изящного сбоя при попытке разобрать строку в целое число. Я бы предположил, что в Python есть что-то встроенное для этого, но я не могу его найти. Если нет, есть ли более Pythonic способ сделать это, который не требует отдельной функции?

def try_parse_int(s, base=10, val=None):
  try:
    return int(s, base)
  except ValueError:
    return val

Решение, которое я использовал в итоге, было модификацией ответа @ sharjeel. Следующее функционально идентично, но, я думаю, более читабельно.

def ignore_exception(exception=Exception, default_val=None):
  """Returns a decorator that ignores an exception raised by the function it
  decorates.

  Using it as a decorator:

    @ignore_exception(ValueError)
    def my_function():
      pass

  Using it as a function wrapper:

    int_try_parse = ignore_exception(ValueError)(int)
  """
  def decorator(function):
    def wrapper(*args, **kwargs):
      try:
        return function(*args, **kwargs)
      except exception:
        return default_val
    return wrapper
  return decorator

Ответы [ 9 ]

44 голосов
/ 14 февраля 2010

Это довольно обычный сценарий, поэтому я написал декоратор ignore_exception, который работает для всех видов функций, которые выдают исключения, а не изящно завершаются сбоем:

def ignore_exception(IgnoreException=Exception,DefaultVal=None):
    """ Decorator for ignoring exception from a function
    e.g.   @ignore_exception(DivideByZero)
    e.g.2. ignore_exception(DivideByZero)(Divide)(2/0)
    """
    def dec(function):
        def _dec(*args, **kwargs):
            try:
                return function(*args, **kwargs)
            except IgnoreException:
                return DefaultVal
        return _dec
    return dec

Использование в вашем случае:

sint = ignore_exception(ValueError)(int)
print sint("Hello World") # prints none
print sint("1340") # prints 1340
22 голосов
/ 07 марта 2012
def intTryParse(value):
    try:
        return int(value), True
    except ValueError:
        return value, False
20 голосов
/ 14 февраля 2010

Это питонский путь. В python принято использовать стиль EAFP - Прошить прощения легче, чем разрешения.
Это означает, что вы сначала попытаетесь, а затем, если необходимо, очистите бардак.

8 голосов
/ 14 февраля 2010

Я бы пошел на:

def parse_int(s, base=10, val=None):
 if s.isdigit():
  return int(s, base)
 else:
  return val

Но это более или менее одно и то же.

7 голосов
/ 14 февраля 2010

Нет, это уже идеально. Параметр val может быть лучше назван по умолчанию.

Задокументировано в официальных документах просто как int (x) - x преобразовано в целое число

2 голосов
/ 18 октября 2016
myList = ['12', '13', '5', 'hope', 'despair', '69','0', '1.2']

myInts = [int(x) for x in myList if x.isdigit()]
1 голос
/ 09 марта 2013
def parseint(string):
    result = '0'
    for x in string:
        if x.isdigit():
        result+=x
    else:
        return int(result)
    return int(result)
1 голос
/ 14 февраля 2010

int () - это встроенный и pythonic способ, как у вас там.

Обычно проще и чаще использовать его напрямую:

def show_square(user_input):
  """Example of using int()."""
  try:
    num = int(user_input, 10)
  except ValueError:
    print "Error" # handle not-an-integer case
    # or you may just want to raise an exception here
    # or re-raise the ValueError
  else:
    print "Times two is", num * 2

def another_example(user_input):
  try:
    num = int(user_input, 10)
  except ValueError:
    num = default
  print "Times two is", num * 2
0 голосов
/ 12 июня 2019

Это может быть другой альтернативой для разбора строки на int

while True:
try:
    n = input("Please enter an integer: ")
    n = int(n)
    break
except ValueError:
    print("No valid integer! Please try again ...")
print("Great, you successfully entered an integer!")
...