Python - Проверка номера телефона перед возвратом - PullRequest
0 голосов
/ 28 февраля 2019

Учитывая, что источник данных, который я использую, очень грязный и может содержать некоторые из следующих элементов в полях "номер телефона":

  • пусто (новый стандарт)
  • !!ЗАКРЫТО !!!!Поэтому я фильтрую класс для форматирования чисел, но я также хочу проверить и просто выбросить его, если это не число.
    class PhoneNumber:
            def __init__( self, number_raw ):
                    number = re.sub('[^0-9]', '', number_raw)
                    self.area_code= number[ 0:3 ]
                    self.exchange = number[ 3:6 ]
                    self.line = number[ 6:13 ]
    
            def __str__( self ):
                    return "({0}) {1}-{2}".format( self.area_code, self.exchange, self.line )
    

    Несколько вещей, которые следует учитывать:

    • Я не могу изменить фактический источник данных
    • Я не могу проверить до достижения этого класса

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

    Какой лучший способ проверить, что входят только цифры, а если строка входит, просто выбросить и вернуть None?


    Потенциальное решение1:

    class PhoneNumber:
            def __init__( self, number_raw ):
                    validation = re.match('[^0-9]', '', number_raw)
                    if validation is False:
                        return None
                    else:
                        number = re.sub('[^0-9]', '', number_raw)
                        self.area_code= number[ 0:3 ]
                        self.exchange = number[ 3:6 ]
                        self.line = number[ 6:13 ]
                        self.full_number = number
    
            def __str__( self ):
                    return "({0}) {1}-{2}".format( self.area_code, self.exchange, self.line )
    

    Потенциальный Soluton 2:

    class PhoneNumber:
            def __init__( self, number_raw ):
                number = re.sub('[^0-9]', '', number_raw)
                self.area_code = number[ 0:3 ]
                self.exchange = number[ 3:6 ]
                self.line = number[ 6:13 ]
                self.og_number = number_raw
    
            def __str__( self ):
                    validation = re.match('[^0-9]', '', self.og_number)
                    if validation is False:
                        return None
                    return "({0}) {1}-{2}".format( self.area_code, self.exchange, self.line )
    

Ответы [ 2 ]

0 голосов
/ 28 февраля 2019

Может быть, просто выполните форматирование в init и примите там свое решение относительно того, есть ли у вас действительный номер или нет?

class FormattedPhoneNumber(object):
  def __init__(self, number):
    try:
      as_number = int(number)
    except (TypeError, ValueError):
      self._formatted = None
    else:
      # you have a number, do whatever formatting you need to do
      area_code = number[ 0:3 ]
      exchange = number[ 3:6 ]
      line = number[ 6:13 ]
      self._formatted = "({0}) {1}-{2}".format(area_code,exchange,line)

  def __str__(self):
    return self._formatted
0 голосов
/ 28 февраля 2019

Нет причин для создания экземпляра объекта со всеми полями, для которых установлено значение Нет.Я бы сделал несколько проверок на __init__, например, так:

class PhoneNumber:
    def __init__(self, number_raw):
        number = int(number_raw)  # do not catch exception here, catch it on instantiation
        number_str = str(number)  # parse to str for slicing

        self.areaCode = number_str[0:3]  # note no space around slicing indexes
        self.exchange = number_str[3:6]
        self.line = number_str[6:13]

Также стоит отметить, что используются переменные, подобные PEP-8, поэтому используйте area_code вместо areaCode.

Второй способ (с использованием classmethod)

Если вам по каким-либо причинам необходимо вернуть None, вы можете найти полезную реализацию с использованием classmethod, например:

class PhoneNumber:
    def __init__(self, number_raw):
        self.areaCode = number_raw[0:3] 
        self.exchange = number_raw[3:6]
        self.line = number_raw[6:13]

    @classmethod
    def instantiate_with_checks(cls, number_raw):
        try:
            int(number_raw)
        except ValueError:
            return None
        # after ensuring that provided variable is valid
        return cls(number_raw)

Создать новый PhoneNumber объект, подобный этому: PhoneNumber.instantiate_with_checks(number_raw).

Третий способ (с использованием __new__):

class PhoneNumber:
    def __init__( self, number_raw ):
        self.area_code = number[0:3]
        self.exchange = number[3:6]
        self.line = number[6:13]

    @classmethod
    def is_number_valid(cls, number_raw):
        try:
            int(number_raw)
        except ValueError:
            return False
        return True

    def __new__(cls, number_raw):
        if cls.is_number_valid(number_raw):
            return super().__new__(cls)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...