用于解析、格式化、存储和验证国际电话号码的 Google 通用库的 Python 版本。
项目描述
电话号码 Python 库
这是Google 的 libphonenumber 库的 Python 端口, 它支持 Python 2.5-2.7 和 Python 3.x(在同一个代码库中,不需要 2to3转换)。
原始 Java 代码版权所有 (C) 2009-2015 The Libphonenumber Authors。
安装
使用pip安装:
pip install phonenumbers
示例用法
库处理的主要对象是PhoneNumber对象。您可以使用该parse函数从表示电话号码的字符串中创建它,但您还需要指定拨打电话号码的国家/地区(除非该号码是 E.164 格式,这是全球唯一的)。
>>> import phonenumbers
>>> x = phonenumbers.parse("+442083661177", None)
>>> print(x)
Country Code: 44 National Number: 2083661177 Leading Zero: False
>>> type(x)
<class 'phonenumbers.phonenumber.PhoneNumber'>
>>> y = phonenumbers.parse("020 8366 1177", "GB")
>>> print(y)
Country Code: 44 National Number: 2083661177 Leading Zero: False
>>> x == y
True
>>> z = phonenumbers.parse("00 1 650 253 2222", "GB") # as dialled from GB, not a GB number
>>> print(z)
Country Code: 1 National Number: 6502532222 Leading Zero(s): False
产生的PhoneNumber对象parse通常仍需要验证,以检查它是可能的数字(例如,它具有正确的位数)还是有效的数字(例如,它在指定的交换中)。
>>> z = phonenumbers.parse("+120012301", None)
>>> print(z)
Country Code: 1 National Number: 20012301 Leading Zero: False
>>> phonenumbers.is_possible_number(z) # too few digits for USA
False
>>> phonenumbers.is_valid_number(z)
False
>>> z = phonenumbers.parse("+12001230101", None)
>>> print(z)
Country Code: 1 National Number: 2001230101 Leading Zero: False
>>> phonenumbers.is_possible_number(z)
True
>>> phonenumbers.is_valid_number(z) # NPA 200 not used
False
对于无法唯一解析或不可能是电话号码的输入,该parse函数也将完全失败(带有 a )。NumberParseException
>>> z = phonenumbers.parse("02081234567", None) # no region, no + => unparseable
Traceback (most recent call last):
File "phonenumbers/phonenumberutil.py", line 2350, in parse
"Missing or invalid default region.")
phonenumbers.phonenumberutil.NumberParseException: (0) Missing or invalid default region.
>>> z = phonenumbers.parse("gibberish", None)
Traceback (most recent call last):
File "phonenumbers/phonenumberutil.py", line 2344, in parse
"The string supplied did not seem to be a phone number.")
phonenumbers.phonenumberutil.NumberParseException: (1) The string supplied did not seem to be a phone number.
获得电话号码后,一项常见任务是将其格式化为标准化格式。有几种可用的格式(在 下PhoneNumberFormat),该format_number函数进行格式化。
>>> phonenumbers.format_number(x, phonenumbers.PhoneNumberFormat.NATIONAL)
'020 8366 1177'
>>> phonenumbers.format_number(x, phonenumbers.PhoneNumberFormat.INTERNATIONAL)
'+44 20 8366 1177'
>>> phonenumbers.format_number(x, phonenumbers.PhoneNumberFormat.E164)
'+442083661177'
如果您的应用程序有一个允许用户键入电话号码的 UI,那么在用户键入时应用格式是很好的。该AsYouTypeFormatter对象允许这样做。
>>> formatter = phonenumbers.AsYouTypeFormatter("US")
>>> formatter.input_digit("6")
'6'
>>> formatter.input_digit("5")
'65'
>>> formatter.input_digit("0")
'650'
>>> formatter.input_digit("2")
'650 2'
>>> formatter.input_digit("5")
'650 25'
>>> formatter.input_digit("3")
'650 253'
>>> formatter.input_digit("2")
'650-2532'
>>> formatter.input_digit("2")
'(650) 253-22'
>>> formatter.input_digit("2")
'(650) 253-222'
>>> formatter.input_digit("2")
'(650) 253-2222'
有时,您有一个较大的文本块,其中可能有也可能没有一些电话号码。为此,PhoneNumberMatcher对象提供了相关功能;您可以对其进行迭代以检索一系列PhoneNumberMatch对象。这些匹配对象中的每一个都包含一个PhoneNumber对象以及有关原始字符串中匹配发生位置的信息。
>>> text = "Call me at 510-748-8230 if it's before 9:30, or on 703-4800500 after 10am."
>>> for match in phonenumbers.PhoneNumberMatcher(text, "US"):
... print(match)
...
PhoneNumberMatch [11,23) 510-748-8230
PhoneNumberMatch [51,62) 703-4800500
>>> for match in phonenumbers.PhoneNumberMatcher(text, "US"):
... print(phonenumbers.format_number(match.number, phonenumbers.PhoneNumberFormat.E164))
...
+15107488230
+17034800500
您可能想要获取有关与电话号码对应的位置的一些信息。在可能的
geocoder.area_description_for_number情况下,这样做。
>>> from phonenumbers import geocoder
>>> ch_number = phonenumbers.parse("0431234567", "CH")
>>> geocoder.description_for_number(ch_number, "de")
'Zürich'
>>> geocoder.description_for_number(ch_number, "en")
'Zurich'
>>> geocoder.description_for_number(ch_number, "fr")
'Zurich'
>>> geocoder.description_for_number(ch_number, "it")
'Zurigo'
对于某些国家/地区的手机号码,您还可以找到有关最初拥有电话号码的运营商的信息。
>>> from phonenumbers import carrier
>>> ro_number = phonenumbers.parse("+40721234567", "RO")
>>> carrier.name_for_number(ro_number, "en")
'Vodafone'
您还可以检索该号码可能属于的时区名称列表。
>>> from phonenumbers import timezone
>>> gb_number = phonenumbers.parse("+447986123456", "GB")
>>> timezone.time_zones_for_number(gb_number)
('Atlantic/Reykjavik', 'Europe/London')
有关库中可用的其他功能的更多信息,请查看单元测试或原始 libphonenumber 项目。
内存使用情况
该库包含大量元数据,可能会产生大量内存开销。有两种机制来处理这个问题。
- 库核心功能的正常元数据(生成的 Python 代码略多于 2 MiB)是按区域按需加载的(即区域的元数据仅在第一次加载时加载)需要)。
- 扩展功能的元数据保存在单独的包中,因此需要单独显式加载。这会影响:
- 地理编码元数据 (~19 MiB),保存在地理编码函数(或
)中
phonenumbers.geocoder并由其使用。geocoder.description_for_numbergeocoder.description_for_valid_numbergeocoder.country_name_for_number - 运营商元数据 (~1 MiB),
phonenumbers.carrier由映射函数 (carrier.name_for_number或carrier.name_for_valid_number) 保存并使用。 - 时区元数据 (~100 KiB),
phonenumbers.timezone由时区函数 (time_zones_for_number或time_zones_for_geographical_number) 保存并使用。
- 地理编码元数据 (~19 MiB),保存在地理编码函数(或
)中
该phonenumberslite库的版本不包括地理编码器、运营商和时区包,如果phonenumbers由于空间/内存限制而安装主库时遇到问题,这可能会很有用。
如果您需要确保元数据内存使用在一天的开始时被考虑(即后续按需加载元数据不会导致暂停或内存耗尽):
- 通过调用强制加载正常的元数据
phonenumbers.PhoneMetadata.load_all()。 import通过使用适当的包 (phonenumbers.geocoder,phonenumbers.carrier,phonenumbers.timezone)强制加载扩展元数据。
该phonenumberslite软件包的版本不包括地理编码、运营商和时区元数据,如果您phonenumbers由于空间/内存限制而在安装主软件包时遇到问题,这可能会很有用。
静态打字
该库包括一组类型存根文件,以支持库用户的静态类型检查。这些存根文件表明应该使用的类型,也可能在具有集成类型检查功能的 IDE 中使用。
这些文件是为 Python 3 编写的,因此不支持在 Python 2.5-2.7 上使用这些存根对库进行类型检查。
项目布局
- 该
python/目录包含 Python 代码。 - 该目录是
来自
libphonenumber
resources/的目录的副本。这不是运行 Python 代码所必需的,但在需要合并对主元数据的上游更改时需要。resources/ - 该
tools/目录包含用于处理对主元数据的上游更改的工具。