Pythonic验证Python中长链条件的方法

nub*_*ela 6 python

所以我有一长串条件应该被证实是真的.if我没有把长条件链接起来,而是试图"创新"并且这样做,我认为这更具可读性.但我的问题是,这是最佳的做法吗?

或者有一种pythonic方式吗?PS:请回答替代方案,而不是回答"否",谢谢!

这是代码块:

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
Run Code Online (Sandbox Code Playgroud)

Mic*_*ber 9

一种更简单的方法是构建条件元组并比较元组:

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
Run Code Online (Sandbox Code Playgroud)

如果您有很多条件,或者条件很昂贵,您可以为条件创建一个生成器,并与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
Run Code Online (Sandbox Code Playgroud)

我不知道的Jython是否有anyall,但他们琐碎的功能来写.

编辑 - anyall出现在Python 2.5中,所以Jython应该有它们.


Seb*_*ask 6

使用异常控制流程很糟糕!它也会扼杀你的表现.假设在十分之一的情况下情况会是真的吗?因此在最坏的情况下处理9个例外 - 这带来了巨大的性能成本.

如果您想要可读性,请尝试:

        if (
            condition1 and \
            condition2 and \
            condition3
            ):
            # do something
Run Code Online (Sandbox Code Playgroud)

对于修订版,这应该是等效的:

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
Run Code Online (Sandbox Code Playgroud)

  • 当代码在括号内时,不需要使用反斜杠. (9认同)
  • @Sebastian Blask:EOL的''''很丑,尤其是在没有必要时. (4认同)
  • 你在说什么?我一直使用控制流的异常.并且它将跳转到第一个异常抛出的`except`子句,因此没有效率问题. (2认同)