考虑到我正在使用的数据源非常脏,并且可能在“电话号码”字段中包含以下内容;
我正在批量导入,并希望确保甚至不打扰这些。因此,我正在筛选一个类以格式化数字,但我也想验证一下,如果不是数字,则将其丢弃。
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 )
潜在解决方案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 )
答案 0 :(得分:1)
没有理由实例化所有字段都设置为None的对象。
我会像这样对__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
。
第二种方式(使用类方法)
如果由于某些原因需要返回None
,则可能会发现使用类方法进行实例化非常有用,例如:
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)
答案 1 :(得分:1)
也许只是在 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