测试 IPv4 地址是否有效
Testing to see if IPv4 address is valid
我想 return 一个布尔值,这取决于给定的地址是否是正确的 IPv4 地址。 python 中内置的 all() 有问题。我已经查看了它的文档,它看起来很简单。话虽如此,我无法让它为我的表达工作。如果您能通俗易懂地解释它是如何工作的,以及我如何更正我的代码,那就太好了。
def IPv4_address(address):
lst_split_address = address.split(".")
slice_split_address = [int(num) for num in lst_split_address[1:]]
if address.count(".") != 3:
return False
elif address == "":
return False
else:
if all(slice_split_address) >= slice_split_address[0]:
return True
else:
return False
print IPv4_address("10.20.30.40")
不要重新发明轮子(除非你乐于维护轮子)。您可以使用正则表达式来验证 ipv4 地址。下面的模式是 taken from Django:
r'(?:25[0-5]|2[0-4]\d|[0-1]?\d?\d)(?:\.(?:25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}'
如果您已经在 Django 项目的上下文中工作,您可能更愿意只导入他们的验证器并直接使用它:
from django.core.validators import validate_ipv4_address
如果您正在使用 Python3,可以使用内置的 ipaddress
模块。
至于你的代码有什么问题,我不相信 all() 函数会按照你认为的那样工作。 all() 期望布尔值的迭代,并且 returns True
如果每个布尔值都是 True
.
为了让它按照您的预期工作,您可能需要像
这样的东西
all(addr_piece >= slice_split_address[0] for addr_piece in slice_split_address)
如 all
的文档所述,它检查列表中的每个元素是否计算为 True
(基本上 bool(e)
是 True
)或者它是否为空.
现在你在 slice_split_address
中有一个整数列表,所以它会检查该列表的每个元素是否计算为 True
如果你只是像你一样调用它并且任何数字不是0 将评估为 True
,但像 127.0.0.1
这样的 IP 实际上是有效的。
所以你需要的实际上是一个包含True
的列表,如果对应的数字在0到255之间(含):
is_valid = [0 <= e <= 255 for e in slice_split_address]
如果你调用 all(is_valid)
它 return 如果 slice_split_address
中的每一项都在 0 到 255 之间。通常它会被组合成类似 all(0 <= e <= 255 for e in slice_split_address)
的东西.
现在您的实施中仍然存在一个问题,因为 slice_split_address
实际上不包含 IP 地址的第一个数字,因此您可以包含它。或者您真的希望第一个数字小于或等于其他三个数字?
此外,您的支票 all(…) >= …
没有意义,因为 all()
仅 returns True
或 False
因此将其与整数进行比较不会真的没有道理。
请注意,all(is_valid)
也会 return True
到像 0.0.0.0
这样的 IP 地址,因此可能需要调整我使用的范围。
正如其他人所说,有更好的方法可以做到这一点。而且您的算法实际上并没有验证 IPv4 地址。但这是您的代码的修复版本。
def IPv4_address(address):
if address.count(".") != 3:
return False
elif address == "":
return False
else:
lst_split_address = address.split(".")
slice_split_address = [int(num) for num in lst_split_address[1:]]
head = slice_split_address[0]
return all(u >= head for u in slice_split_address)
print IPv4_address("10.20.30.40")
输出
True
我已将 lst_split_address
内容移到 else
块中,因为如果 if / elif 部分 return False,则无需执行此操作。
all(u >= head for u in slice_split_address)
使用一个简单的生成器表达式来检查 slice_split_address
中的所有项目是否 >= 头项目。
我想 return 一个布尔值,这取决于给定的地址是否是正确的 IPv4 地址。 python 中内置的 all() 有问题。我已经查看了它的文档,它看起来很简单。话虽如此,我无法让它为我的表达工作。如果您能通俗易懂地解释它是如何工作的,以及我如何更正我的代码,那就太好了。
def IPv4_address(address):
lst_split_address = address.split(".")
slice_split_address = [int(num) for num in lst_split_address[1:]]
if address.count(".") != 3:
return False
elif address == "":
return False
else:
if all(slice_split_address) >= slice_split_address[0]:
return True
else:
return False
print IPv4_address("10.20.30.40")
不要重新发明轮子(除非你乐于维护轮子)。您可以使用正则表达式来验证 ipv4 地址。下面的模式是 taken from Django:
r'(?:25[0-5]|2[0-4]\d|[0-1]?\d?\d)(?:\.(?:25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}'
如果您已经在 Django 项目的上下文中工作,您可能更愿意只导入他们的验证器并直接使用它:
from django.core.validators import validate_ipv4_address
如果您正在使用 Python3,可以使用内置的 ipaddress
模块。
至于你的代码有什么问题,我不相信 all() 函数会按照你认为的那样工作。 all() 期望布尔值的迭代,并且 returns True
如果每个布尔值都是 True
.
为了让它按照您的预期工作,您可能需要像
这样的东西all(addr_piece >= slice_split_address[0] for addr_piece in slice_split_address)
如 all
的文档所述,它检查列表中的每个元素是否计算为 True
(基本上 bool(e)
是 True
)或者它是否为空.
现在你在 slice_split_address
中有一个整数列表,所以它会检查该列表的每个元素是否计算为 True
如果你只是像你一样调用它并且任何数字不是0 将评估为 True
,但像 127.0.0.1
这样的 IP 实际上是有效的。
所以你需要的实际上是一个包含True
的列表,如果对应的数字在0到255之间(含):
is_valid = [0 <= e <= 255 for e in slice_split_address]
如果你调用 all(is_valid)
它 return 如果 slice_split_address
中的每一项都在 0 到 255 之间。通常它会被组合成类似 all(0 <= e <= 255 for e in slice_split_address)
的东西.
现在您的实施中仍然存在一个问题,因为 slice_split_address
实际上不包含 IP 地址的第一个数字,因此您可以包含它。或者您真的希望第一个数字小于或等于其他三个数字?
此外,您的支票 all(…) >= …
没有意义,因为 all()
仅 returns True
或 False
因此将其与整数进行比较不会真的没有道理。
请注意,all(is_valid)
也会 return True
到像 0.0.0.0
这样的 IP 地址,因此可能需要调整我使用的范围。
正如其他人所说,有更好的方法可以做到这一点。而且您的算法实际上并没有验证 IPv4 地址。但这是您的代码的修复版本。
def IPv4_address(address):
if address.count(".") != 3:
return False
elif address == "":
return False
else:
lst_split_address = address.split(".")
slice_split_address = [int(num) for num in lst_split_address[1:]]
head = slice_split_address[0]
return all(u >= head for u in slice_split_address)
print IPv4_address("10.20.30.40")
输出
True
我已将 lst_split_address
内容移到 else
块中,因为如果 if / elif 部分 return False,则无需执行此操作。
all(u >= head for u in slice_split_address)
使用一个简单的生成器表达式来检查 slice_split_address
中的所有项目是否 >= 头项目。