Python:如何生成一个随机的phone数?
Python: How to generate a random phone number?
不是 Making random phone number xxx-xxx-xxxx
的副本
我的项目使用 python-phonenumbers and django-phonenumber-field 进行 phone 数字验证。在项目中有大量自定义验证规则,像这样的天真方法是不够的:
>>> import functools
>>> import random
>>> a = functools.partial(random.randint, 0, 9)
>>> gen = lambda: "+{}-{}{}{}-{}{}{}-{}{}{}{}".format(a(), a(), a(), a(), a(), a(), a(), a(), a(), a(), a())
>>> gen()
'+2-758-702-0180' # Obviously wrong
>>> gen()
'+1-911-555-0180' # Obviously wrong, it has 911 in it
因此,在不求助于没有上限的强力 while 循环,并且不为此类微不足道的问题引入上限的情况下,有什么更好的方法来生成有效的 phone 数字接受验证者本身?
from phonenumber_field.validators import validate_international_phonenumber
from django.core.exceptions import ValidationError
def generate_valid_number():
while True: # While loops are not desired, even with an upper bound!
try:
number = gen()
validate_international_phonenumber(number)
return number
except ValidationError:
pass
我认为 davidn 给 this question 的答案应该有效,尤其是因为您已经在使用 python-phonenumbers
I would recommend to use the phonenumbers package which is a python
port of Google's libphonenumber which includes a data set of mobile
carriers now:
import phonenumbers
from phonenumbers import carrier
from phonenumbers.phonenumberutil import number_type
number = "+49 176 1234 5678"
carrier._is_mobile(number_type(phonenumbers.parse(number)))
This will
return True in case number is a mobile number or False otherwise. Note
that the number must be a valid international number or an exception
will be thrown. You can also use phonenumbers to parse phonenumber
given a region hint.
如果您使用的是包 faker
,您可以编写一个可以在您的项目中重复使用的自定义提供程序。
import phonenumbers
from faker.providers.phone_number.en_US import Provider
class CustomPhoneProvider(Provider):
def phone_number(self):
while True:
phone_number = self.numerify(self.random_element(self.formats))
parsed_number = phonenumbers.parse(phone_number, 'US')
if phonenumbers.is_valid_number(parsed_number):
return phonenumbers.format_number(
parsed_number,
phonenumbers.PhoneNumberFormat.E164
)
与factory_boy
一起使用:
import factory
from faker import Faker
from .models import User
from .providers import CustomPhoneProvider
fake = Faker()
fake.add_provider(CustomPhoneProvider)
class UserFactory(factory.DjangoModelFactory):
class Meta:
model = User
first_name = factory.Faker('first_name')
last_name = factory.Faker('last_name')
phone_number = factory.LazyAttribute(lambda _: fake.phone_number())
不是 Making random phone number xxx-xxx-xxxx
的副本我的项目使用 python-phonenumbers and django-phonenumber-field 进行 phone 数字验证。在项目中有大量自定义验证规则,像这样的天真方法是不够的:
>>> import functools
>>> import random
>>> a = functools.partial(random.randint, 0, 9)
>>> gen = lambda: "+{}-{}{}{}-{}{}{}-{}{}{}{}".format(a(), a(), a(), a(), a(), a(), a(), a(), a(), a(), a())
>>> gen()
'+2-758-702-0180' # Obviously wrong
>>> gen()
'+1-911-555-0180' # Obviously wrong, it has 911 in it
因此,在不求助于没有上限的强力 while 循环,并且不为此类微不足道的问题引入上限的情况下,有什么更好的方法来生成有效的 phone 数字接受验证者本身?
from phonenumber_field.validators import validate_international_phonenumber
from django.core.exceptions import ValidationError
def generate_valid_number():
while True: # While loops are not desired, even with an upper bound!
try:
number = gen()
validate_international_phonenumber(number)
return number
except ValidationError:
pass
我认为 davidn 给 this question 的答案应该有效,尤其是因为您已经在使用 python-phonenumbers
I would recommend to use the phonenumbers package which is a python port of Google's libphonenumber which includes a data set of mobile carriers now:
import phonenumbers from phonenumbers import carrier from phonenumbers.phonenumberutil import number_type number = "+49 176 1234 5678" carrier._is_mobile(number_type(phonenumbers.parse(number)))
This will return True in case number is a mobile number or False otherwise. Note that the number must be a valid international number or an exception will be thrown. You can also use phonenumbers to parse phonenumber given a region hint.
如果您使用的是包 faker
,您可以编写一个可以在您的项目中重复使用的自定义提供程序。
import phonenumbers
from faker.providers.phone_number.en_US import Provider
class CustomPhoneProvider(Provider):
def phone_number(self):
while True:
phone_number = self.numerify(self.random_element(self.formats))
parsed_number = phonenumbers.parse(phone_number, 'US')
if phonenumbers.is_valid_number(parsed_number):
return phonenumbers.format_number(
parsed_number,
phonenumbers.PhoneNumberFormat.E164
)
与factory_boy
一起使用:
import factory
from faker import Faker
from .models import User
from .providers import CustomPhoneProvider
fake = Faker()
fake.add_provider(CustomPhoneProvider)
class UserFactory(factory.DjangoModelFactory):
class Meta:
model = User
first_name = factory.Faker('first_name')
last_name = factory.Faker('last_name')
phone_number = factory.LazyAttribute(lambda _: fake.phone_number())