仅当值不为 None 时应用函数的 Python 习惯用法

问题描述 投票:0回答:3

一个函数正在接收许多都是字符串的值,但需要以各种方式进行解析,例如

vote_count = int(input_1)
score = float(input_2)
person = Person(input_3)

这一切都很好,除了输入也可以是

None
,在这种情况下,我不想解析值,而是希望将
None
分配给左侧。这可以通过

来完成
vote_count = int(input_1) if input_1 is not None else None
...

但这似乎可读性较差,尤其是像这样的许多重复行。我正在考虑定义一个函数来简化这个过程,比如

def whendefined(func, value):
    return func(value) if value is not None else None

可以这样使用

vote_count = whendefined(int, input_1)
...

我的问题是,这有一个常见的习语吗?可能使用内置的 Python 函数?即使没有,这样的函数有一个常用的名称吗?

python nonetype
3个回答
6
投票

在其他语言中,有选项类型,它有点不同(用类型系统解决问题),但具有相同的动机(如何处理空值)。

在Python中,更多地关注此类事情的运行时检测,因此您可以使用无检测保护(而不是选项类型所做的数据)来包装函数。

您可以编写一个装饰器,仅在参数不为 None 时才执行函数:

def option(function):
    def wrapper(*args, **kwargs):
        if len(args) > 0 and args[0] is not None:
          return function(*args, **kwargs)
    return wrapper

您可能应该调整第三行,使其更适合您正在使用的数据类型。

使用中:

@option
def optionprint(inp):
    return inp + "!!"

>>> optionprint(None)
# Nothing

>>> optionprint("hello")
'hello!!'

并且有返回值

@option
def optioninc(input):
    return input + 1

>>> optioninc(None)
>>> # Nothing

>>> optioninc(100)
101

或者包装一个类型构造函数

>>> int_or_none = option(int)
>>> int_or_none(None)
# Nothing
>>> int_or_none(12)
12

4
投票

如果您可以安全地将假值(例如 0 和空字符串)视为 None,则可以使用布尔值和:

vote_count = input_1 and int(input_1)

因为看起来您正在使用字符串作为输入,所以这可能会起作用;无论如何,你不能将空字符串转换为 int 或 float (或 person)。尽管这个习惯用法在 Lua 中很常用,但对于某些人来说,它的可读性并不是很强。


0
投票

opytional
使用受 C++
std::optional
启发的界面很好地表达了这种模式。

>>> import opytional as opyt
>>> input_1 = "3"
>>> opyt.apply_if(input_1, int)
"1"
>>> input_2 = None
>>> opyt.apply_if(input_2, int)
None

该库还提供

or_else
or_value
来安全、富有表现力地处理可能为 None 的值。可通过 pip 进行安装,
python3 -m pip install opytional

免责声明:我是图书馆作者

© www.soinside.com 2019 - 2024. All rights reserved.