Есть ли библиотека Python (или шаблон), как Ruby's andand?
Например, у меня есть объект x
это может быть None
или строковое представление числа с плавающей точкой. Я хочу сделать следующее:
do_stuff_with(float(x) if x else None)
За исключением того, что не нужно вводить x
дважды, как в случае с Ruby's andand library:
require 'andand'
do_stuff_with(x.andand.to_f)
2 ответа
У нас нет одного из них, но это не трудно свернуть свой собственный:
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
Исходя из идеи Рэймонда, вот фабрика по производству условных упаковок такого типа. Зачем писать им самим, если вы можете сделать так, чтобы 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
В вашем случае использования, я думаю, что этот подход является выигрышным: он прозрачно имеет дело со всем, что может быть преобразовано в float
и делает "правильные вещи", если обманчиво, но обратимо кfloat
значение (например, 0) передается в.