在Python中验证一长串条件的优雅方式
我有一长串条件需要验证是否为真。为了避免写一大堆的if
条件,我想尝试一种“创新”的方式,这样我觉得更容易读懂。但是我想问,这样做是否是最优的方式?
或者有没有更符合Python风格的做法?顺便说一下,请给我一个替代方案,而不是直接回答“不是”,谢谢!
以下是代码片段:
def site_exists(site):
"""
returns the sitebean if it exists,
else returns false
"""
vpadmin_service = _get_vpadmin_service(site)
all_sites = VpAdminServiceUtil.getSites(vpadmin_service)
for site_listing in all_sites:
if site.getId():
#condition check
try:
assert site.getId() == site_listing.getId()
assert site.getName() == site_listing.getName()
assert site.getCustomer().getId() == site_listing.getCustomer().getId()
except AssertionError:
continue
#pass conditions
return site_listing
#no id, so just check for name and customer
else:
#condition check
try:
assert site.getName() == site_listing.getName()
assert site.getCustomer().getId() == site_listing.getCustomer().getId()
except AssertionError:
continue
#pass conditions
site.setId(site_listing.getId())
return site_listing
return False
7 个回答
3
我会在 site
上实现一个 is_same
方法,然后在 for
循环中调用它。
all_sites = VpAdminServiceUtil.getSites(vpadmin_service)
for site_listing in all_sites:
if site_listing.is_same(site, set_id=True):
return site_listing
至于如何实现这个方法(这才是你真正想问的问题),我建议可以这样做:
...
if self.getName() != site.getName(): return False
if self.getCustomer() != site.getCustomer(): return False
...
return True
10
一种更简单的方法是把条件放在一个元组里,然后比较这些元组:
def site_info(s):
return s.getId(), s.getName(), s.getCustomer().getId()
if site_info(site) == site_info(site_listing):
return site_listing
else:
continue
如果你有很多条件,或者这些条件比较复杂,另一种方法是创建一个生成器来处理这些条件,然后用 any
或 all
来比较:
import itertools
def iter_site_info(s):
yield s.getId()
yield s.getName()
yield s.getCustomer().getId()
if all(x==y for (x, y) in itertools.izip(iter_site_info(site), iter_site_info(site_listing)):
return site_listing
else:
continue
我不确定 Jython 是否有 any
和 all
这两个功能,但其实写这两个功能很简单。
补充 - any
和 all
是在 Python 2.5 版本中出现的,所以 Jython 应该也有这两个功能。
6
用异常来控制程序的流程是不好的!而且这样会严重影响你的性能。假设某个条件在10次中只有1次会成立?那么在最糟糕的情况下,你就得处理9个异常,这样会带来很大的性能损失。
如果你想让代码更容易读懂,可以试试:
if (
condition1 and \
condition2 and \
condition3
):
# do something
对于修改后的版本,这应该是等价的:
for site_listing in all_sites:
if site.getName() == site_listing.getName() and site.getCustomer().getId() == site_listing.getCustomer().getId():
if not site.getId():
site.setId(site_listing.getId())
if site.getId() == site_listing.getId():
return site_listing