如何用更少的代码替换多个try / except块?

时间:2014-11-18 23:19:20

标签: python

我发现自己编写的代码如下所示。它非常冗长。我想做的是将数组indeces分配给不同的变量,如果有indexerror,则赋值false。我觉得这样做的语法应该更短(与下面的内容相比)。

编辑 - 这是我的实际代码。 page是一个有效的lxml.html对象。每个选择器可能会也可能不会返回一个值,具体取决于该部分是否出现在页面上。

def extract_data( page ):
    # given lxml.html obj, extract data from g+ page and return as dict
    try:
        profile_name = page.xpath( '//div[@guidedhelpid="profile_name"]/text()' )[0]
    except IndexError:
        profile_name = False
    try:
        website = page.cssselect( 'span.K9a' )[0].text_content().rstrip('/')
    except IndexError:
        website = False

    try:
        contact_div = html.tostring( page.xpath( '//div[normalize-space(text())="Contact Information"]/../../..' )[0] )
    except IndexError:
        contact_div = False

    return {
        'profile_name'      :   profile_name,
        'website'           :   website,
        'contact_div'       :   contact_div,
    }

3 个答案:

答案 0 :(得分:3)

假设您在用例的上下文中尝试做的事情是有意义的,您可以将这个默认值的概念封装在函数中:

def retrieve(my_list, index, default_value=False):
    try:
        return my_list[index]
    except IndexError:
        return default_value

这样你可以做类似的事情:

my_list = [2, 4]
first = retrieve(my_list, 0)
# first will be 2
second = retrieve(my_list, 1)
# second will be 4
third = retrieve(my_list, 2)
# third will be False

如果索引不存在,您甚至可以更改您要默认的值。

一般情况下,当您按照上述方式重复代码时,首先要考虑的是您是否可以编写一个能够执行您尝试的功能的功能。做。


使用您的实际代码,您可以执行以下操作:

profile_name = retrieve(page.xpath( '//div[@guidedhelpid="profile_name"]/text()'), 0)
website = retrieve(page.cssselect( 'span.K9a' ), 0)
if website:
    website = website.text_content().rstrip('/')
contact_div = retrieve(page.xpath( '//div[normalize-space(text())="Contact Information"]/../../..' ), 0)
if contact_div:
    contact_div = html.tostring(contact_div)

答案 1 :(得分:1)

vars = ['first', 'second', 'third']
r = {}
for i, var in enumerate(vars):
    try:
        r[var] = l[i]
    except IndexError:
        r[var] = False

答案 2 :(得分:0)

这应该解决你的问题:) exec +循环救援!

l = list([0,2])

numberWords = { 0:"first", 1:"second", 2:"third"}

for i in range(0,len(l)):
    try:
        exec(numberWords[i]+"=l["+str(i)+"]")
    except IndexError:
        exec(numberWords[i]+"=false")