例如,我有一个x
可能是None
浮点数的对象或字符串表示形式。我想做以下事情:
do_stuff_with(float(x) if x else None)
除了不必键入x
两次,如 Ruby 的andand库:
require 'andand'
do_stuff_with(x.andand.to_f)
我们没有其中之一,但不难推出自己的:
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
开始考虑 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
不完全是 Pythonic,但我不知道有一个更好的名字。也许trap
是因为您捕获了无效值。
值得注意的是,一个常见的 Python 习语是继续尝试做你需要做的事情,并在出现异常时处理它们。这被称为 EAFP,来自格言“请求宽恕比许可更容易”。所以也许一种更 Pythonic 的写法是:
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
在您的用例中,我认为这种方法是一个胜利:它透明地处理任何可以转换为 afloat
的东西,并且如果传递了一个虚假但可转换为float
值(例如 0)的值,它会做“正确的事情”在。