Setting a variable to a parameter value inline when calling a function

Viewed 99

In other languages, like Java, you can do something like this:

String path;
if (exists(path = "/some/path"))
    my_path = path;

the point being that path is being set as part of specifying a parameter to a method call. I know that this doesn't work in Python. It is something that I've always wished Python had.

Is there any way to accomplish this in Python? What I mean here by "accomplish" is to be able to write both the call to exists and the assignment to path, as a single statement with no prior supporting code being necessary.

I'll be OK with it if a way of doing this requires the use of an additional call to a function or method, including anything I might write myself. I spent a little time trying to come up with such a module, but failed to come up with anything that was less ugly than just doing the assignment before calling the function.

UPDATE: @BrokenBenchmark's answer is perfect if one can assume Python 3.8 or better. Unfortunately, I can't yet do that, so I'm still searching for a solution to this problem that will work with Python 3.7 and earlier.

2 Answers

Yes, you can use the walrus operator if you're using Python 3.8 or above:

import os
if os.path.isdir((path := "/some/path")):
    my_path = path

I've come up with something that has some issues, but does technically get me where I was looking to be. Maybe someone else will have ideas for improving this to make it fully cool. Here's what I have:

# In a utility module somewhere

def v(varname, arg=None):
    if arg is not None:
        if not hasattr(v, 'vals'):
            v.vals = {}
        v.vals[varname] = arg
    return v.vals[varname]

# At point of use

if os.path.exists(v('path1', os.path.expanduser('~/.harmony/mnt/fetch_devqa'))):
    fetch_devqa_path = v('path1')

As you can see, this fits my requirement of no extra lines of code. The "variable" involved, path1 in this example, is stored on the function that implements all of this, on a per-variable-name basis.

One can question if this is concise and readable enough to be worth the bother. For me, the verdict is still out. If not for the need to call the v() function a second time, I think I'd be good with it structurally.

The only functional problem I see with this is that it isn't thread-safe. Two copies of the code could run concurrently and run into a race condition between the two calls to v(). The same problem is greatly magnified if one fails to choose unique variable names every time this is used. That's probably the deal killer here.

Can anyone see how to use this to get to a similar solution without the drawbacks?

Related