Python嵌套尝试除了vs if,elif,else

时间:2016-05-05 02:02:45

标签: python if-statement try-except

我正在努力熟悉Python的最佳实践。根据Python的Zen,请求宽恕比要求许可更容易,但是,它也说平面比嵌套和可读性更好。你会怎么处理这个问题:

我有3本词典。我有一把钥匙,我想测试钥匙是否在字典中。钥匙只会出现在其中一个中。根据它所在的词典,我想做不同的事情。

使用try / except,我得出以下解决方案:

try:
    val = dict1[key]
except KeyError:
    try:
        val = dict2[key]
    except KeyError:
        try:
            val = dict3[key]
        except KeyError:
            do_stuff_key_not_found()
        else:
            do_stuff_dict3()
    else:
        do_stuff_dict2()
else:
    do_stuff_dict1()

根据Python的EAFP原则,这将是一种方法,但它看起来很混乱,并且不太可读。

更简单的解决方案是:

if key in dict1:
    val = dict1[key]
    do_stuff_dict1()
elif key in dict2:
    val = dict2[key]
    do_stuff_dict2()
elif key in dict3:
    val = dict3[key]
    do_stuff_dict3()
else:
    do_stuff_key_not_found()

更像Pythonic处理这样一个案例的方法是什么?我应该坚持EAFP原则,还是平坦且可读性更重要?

2 个答案:

答案 0 :(得分:6)

在许多情况下,EAFP是一个合理的格言,但它并不是一个可以被盲目追随的格言。在你的例子中,我会说if / elif版本没有任何可怕的错误。

两个版本都涉及代码重复,如果你有大量的案例要处理,可能会变得难以处理。解决这个问题的一种方法是将字典/函数对拉出到列表中,然后迭代列表:

SQLException: Error in allocating a connection. Cause: Connection could not be allocated because: ORA-00604: error occurred at recursive SQL level 1
ORA-20001: DBT Error in AUDIT_SESSION_TRIG
ORA-06512: at line 20
ORA-01653: unable to extend table DBT.SESSION_AUDIT by 1280 in tablespace DBT_DATA_5G

    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:328)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:106)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1360)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1118)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
    at org.codehaus.groovy.grails.commons.spring.ReloadAwareAutowireCapableBeanFactory.doCreateBean(ReloadAwareAutowireCapableBeanFactory.java:126)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:322)
    ... 64 more
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'lobHandlerDetector': Invocation of init method failed; nested exception is org.springframework.jdbc.support.MetaDataAccessException: Error while extracting DatabaseMetaData; nested exception is java.sql.SQLException: Error in allocating a connection. Cause: Connection could not be allocated because: ORA-00604: error occurred at recursive SQL level 1

答案 1 :(得分:1)

我更喜欢使用dict.get(key,default_value)来避免异常处理,例如:

8004020e
  

get(key [,default])   如果key在,则返回key的值   字典,否则默认。如果未给出default,则默认为   无,因此此方法永远不会引发KeyError。   https://docs.python.org/2/library/stdtypes.html