Swift Python 中的可选项(或 Haskell 的可能)?

Swift Optionals (or Haskell's Maybe) in Python?

在Swift我可以做到var?.prop。如果 varnil,则结果为 nil,否则结果为 varprop 属性 的值。

等价地,我可以在 Haskell 中执行 var >>= prop,这让我得到 NonevarNone,否则它给我的价值将 prop 应用于 var 中的值(包装在 Just 中)。

在Python中是否有等价物?

长话短说,没有特殊的语法来处理可选值(因为没有可选值),尽管您可以使用条件赋值(三元运算符)来模拟功能:

unpacked_var = var.prop if var is not None else None

尽管在 Python 中,我宁愿检查 var 是否具有您要访问的属性。

unpacked_var = var.prop if hasattr(var, "prop") else None

你可以写一个函数让它更短

def optional(var, attr):
    return getattr(var, attr) if hasattr(var, attr) else None

unpacked_var = optional(var, "prop")

有一种不太通用的方法(恕我直言,不太明确):

unpacked_var = hasattr(var, "prop") and var.prop or None

这里的问题是,如果 bool(var.prop) == False,你会得到 None,所以你最好坚持使用上面的三元运算符。

其他答案在建议条件表达式方面走上了正确的道路,但在如何去做方面却错了。你可以这样做:

None if var is None else var.prop

或者,等价地

var.prop if var is not None else None

有一个 draft PEP 关于将这样的功能添加到 Python,并且已经在 Python-ideas 邮件列表中讨论过它。它看起来不会在不久的将来添加(如果有的话),但阅读 PEP 会让您了解一些现有的和建议的处理方法。

使用 None 可能很难维护干净的调用站点代码。这意味着你需要有很多防御条件。从其他回答可以看出,这种方法得到了很多聪明人的支持。

另一种方法是使用可选类型,它很像集合类型(list、set、dict 等),明确表示为空或非空,但与其他类型不同集合类型,只能容纳 1 个元素。这意味着您的所有 return 来自函数 return 具有相同功能的对象。就像 returning 一个集合一样,当事情出错但不是特别如此时,你可以 return 该集合的空版本(例如,数据库中没有超过 100 岁的用户)你可以使用可选类型来做同样的事情(例如,数据库中没有用户名为 foobar 的用户)。

由于 python 没有内置可选类型,我创建了一个提供它的小型库:optional.py。您可以使用 'pip install optional.py' 进行尝试。我欢迎评论、功能请求和贡献。