有没有类似Ruby中andand的Python库(或模式)?
比如,我有一个对象 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