有没有类似Ruby中andand的Python库(或模式)?

6 投票
2 回答
562 浏览
提问于 2025-04-17 05:01

比如,我有一个对象 x,它可能是 None(表示没有值)或者是一个浮点数的字符串。我想要做的事情是:

do_stuff_with(float(x) if x else None)

但是我不想像在Ruby的 andand 库那样,输入 x 两次:

require 'andand'
do_stuff_with(x.andand.to_f)

2 个回答

4

基于Raymond的想法,这里有一个工厂,用来制作这种条件包装器。为什么要自己写这些东西呢,Python可以帮你写!

def makeandand(func):
    return lambda x: func(x) if x else None

andandfloat = makeandand(float)

andandfloat('10.25')
>>> 10.25

andandfloat('')
>>> None

andand这个名字虽然不太符合Python的风格,但我一时想不到更好的名字。也许叫trap比较合适,因为你是在捕捉无效的值。

值得注意的是,Python有个常见的做法,就是直接尝试去做你需要做的事情,然后再处理出现的异常。这种方法叫做EAFP,意思是“请求原谅比请求许可更简单”。所以,也许用更符合Python风格的方式来写是:

def maketrap(func, *exceptions):
    def trap(x):
        try:
            return func(x)
        except exceptions or (Exception,):
            return None
    return andand

trapfloat = maketrap(float)

# optionally specify the exceptions to convert to a None return
# (default is to catch anything but you may want to allow some through)
trapfloat = maketrap(float, ValueError)
trapfloat = maketrap(float, ValueError, TypeError)

# if you don't want to store it (i.e. you only need it once or twice)...
maketrap(float)(x)    # ... just call it immediately

在你的使用场景中,我觉得这种方法是个好主意:它可以透明地处理任何可以转换为float的东西,并且如果传入一个可以转换为float的假值(比如0),它会做出“正确的处理”。

9

我们没有那种东西,但自己做一个并不难:

def andand(x, func):
    return func(x) if x else None

>>> x = '10.25'
>>> andand(x, float)
10.25
>>> x = None
>>> andand(x, float) is None
True

撰写回答