2

For example, what assert does:

assert <boolean assertion to check>, <error string/value outputted if that assertion False>

What I would like to do:

mycommand <boolean assertion to check>, <value that will get returned if assertion is False>

It would be the same as doing:

if not <boolean assertion to check>: return <value>

but concisely, with a simple one-liner. I know I should just use this last one, but I am more interested on finding out how much you can override/customize python.

6
  • 1
    You can't. The closest you can get is a function (although obviously you can't handling returning from a separate function). You could write your own preprocessor or try finding an existing one, but there's no built-in way. Commented Nov 20, 2019 at 15:15
  • Might be worth reading through this question: stackoverflow.com/questions/15669921/adding-macros-to-python Commented Nov 20, 2019 at 15:19
  • 1
    If you write code that needs so many of these kinds of statements that you're thinking about customising Python like this, then I'd suggest you should rather write the code differently, as that sounds like a red flag. 😉 Commented Nov 20, 2019 at 15:23
  • Or write in a lisp where this kind of thinking is common and even encouraged (I recommend Clojure). Commented Nov 20, 2019 at 15:23
  • @deceze I knew I was going to get this answer and you are probably right lol.. anyway, what if I have to perform multiple checks on a Flask GET instance for some json content? [current snippet] (i.imgur.com/u8FbMSu.png) Commented Nov 21, 2019 at 12:31

2 Answers 2

2

You can not use any "user-defined" syntax, but you could just use assert itself and use a decorator to make the function return the value instead of raising an AssertionError:

def assert_to_return(f):
    def _f(*args, **kwargs):
        try:
            return f(*args, **kwargs)
        except AssertionError as e:
            return e.args[0] if e.args else None
    return _f

@assert_to_return
def div(x, y):
    assert y != 0, float("nan")
    return x / y

print(div(42, 5)) # 8.4
print(div(42, 0)) # nan

This way, the assert <condition>, <value> line means "check whether <condition> holds, otherwise immediately return <value>", i.e. pretty much exactly what you wanted. If the <value> is omitted, the function will just return None in that case, as defined in the decorator. Also note that <value> is only evaluated if the assert is violated, i.e. it could also contain an expensive function call or side-effects that you do not want to occur otherwise.

Of course, while other exceptions will work just fine, any AssertionError raised by assert statements in functions your function is calling will also bei caught and handled by the decorator. If this is a problem, you could either (a) wrap the <value> in some special wrapper object and only return those in _f, otherwise re-raise the AssertionError, or (b) wrap all the functions you call in your function that might also raise an AssertionError so that their AssertionErrors are wrapped in another exception.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for the answer! I think this is the closest to what I was looking for. It's interesting to see a solution that involves decorators, I didn't know much about them.
2

If what you are looking for a one-expression if statement (rather than an assertion that causes failure if false), then do this:

<value> if <boolean assertion to check> else <another value>

If you don't have anything for <another value>, it is Pythonic to let that be None.

x = 3 if 10<5 else None gives x the value None.

x = 3 if 10>5 else None gives x the value 3.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.