Is there a Python library (or pattern) like Ruby&#

2019-06-18 14:56发布

For example, I have an object x that might be None or a string representation of a float. I want to do the following:

do_stuff_with(float(x) if x else None)

Except without having to type x twice, as with Ruby's andand library:

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

2条回答
Anthone
2楼-- · 2019-06-18 15:43

We don't have one of those but it isn't hard to roll your own:

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
查看更多
兄弟一词,经得起流年.
3楼-- · 2019-06-18 15:50

Taking off on Raymond's idea, here's a factory for making conditional wrappers of this sort. Why write 'em yourself when you can have Python write 'em for you?

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

andandfloat = makeandand(float)

andandfloat('10.25')
>>> 10.25

andandfloat('')
>>> None

andand isn't exactly Pythonic, but I'm at a loss for a better name. Maybe trap since you're trapping the invalid value.

It's worth noting that a common Python idiom is to go ahead and try to do what you need to do, and deal with exceptions as they come along. This is called EAFP, from the maxim "it's Easier to Ask Forgiveness than Permission." So maybe a more Pythonic way to write that is:

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

In your use case, I think this approach is a win: it transparently deals with anything that can be converted to a float, and does "the right thing" if a falsy-but-convertible-to-float value (such as 0) is passed in.

查看更多
登录 后发表回答