【问题标题】:How can I make string parsing in Python less unwieldy?如何使 Python 中的字符串解析变得不那么笨拙?
【发布时间】:2018-10-22 14:18:24
【问题描述】:

如果问题标题过于含糊,我们深表歉意 - 欢迎编辑。

我正在尝试使用 BeautifulSoup 解析 XML,但是因为每个函数调用都可能返回 None,所以我必须在多行中解析单个元素。这很快就会变得笨拙:

books_count = result.books_count

if not books_count:
    return None

books_count = books_count.string

if not books_count:
    return None

books_count = int(books_count)

if not books_count:
    return None

在 Swift 中做同样的事情,这是一种我更熟悉的语言,它更简洁:

guard let booksCountString = result.booksCount?.string,
    let booksCountInt = Int(booksCountString) else {
    return nil
}

有没有类似的方法可以在 Python 中做到这一点?我想避免使用 try/catch,因为它可能会在我的代码中不断出现运行时错误,这感觉不是很好的做法。

【问题讨论】:

  • 为什么你认为使用 try/catch 感觉不是很好的做法
  • 对于 Python,“请求宽恕比请求许可 (EAFP) 更容易”。 Python EAFP 编码风格假设存在某些属性或元素,如果假设被证明是错误的,则捕获异常。所以使用try ... catch 是完全可以的。这是与许多其他语言常见的“先看后跳”(LBYL)风格形成对比的技术。如果您仍然不习惯这种做法,也许您应该提供更多代码细节,以便更好地了解您正在尝试做的事情的上下文。
  • 导致它可能不断出现运行时错误 - 您可以避免只捕获所需的异常。例如,except (AttributeError, ValueError)
  • 我认为您正在寻求使解析 wieldier (或更实用),尽管这些词在大多数英语方言中都很少出现;我认为大多数以母语为母语的人都会问如何使解析不那么笨重

标签: python string parsing beautifulsoup


【解决方案1】:

如果您使用 lambdas 表示您的 None 检查序列,如下所示:

check_1 = lambda r: r.books_count
check_2 = lambda r: r.string
check_3 = lambda r: int(r)

然后我们可以为任意数量的这些检查概括出一个解决方案。这个函数(在某种程度上)类似于functools.reduce 的工作方式:

def my_reduce(fs, arg, stop_value=None):
    res = arg
    for f in fs:
        res = f(res)
        if res == stop_value:
            return stop_value
    return res

然后像这样使用它:

my_reduce([check_1, check_2, check_3], good_value)
Out[1]: 42

my_reduce([check_1, check_2, check_3], bad_value) is None
Out[2]: True

【讨论】:

    【解决方案2】:

    也许在 for 循环中?

    example = [result.books_count, books_count.string, int(books_count)]

    for n in example: if not n : return None

    刚刚对其进行了测试,只要result.books_count, books_count.string, int(books_count) 没有引发任何错误,for 循环就可以正常工作

    【讨论】:

      猜你喜欢
      • 2011-10-17
      • 1970-01-01
      • 1970-01-01
      • 2023-03-05
      • 2011-02-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-05
      相关资源
      最近更新 更多