How to assign a variable in an IF condition, and then return it?
I see somebody else has already pointed to my old "assign and set" Cookbook recipe, which boils down in its simplest version to:
class Holder(object):
def set(self, value):
self.value = value
return value
def get(self):
return self.value
h = Holder()
...
if h.set(isBig(y)): return h.get()
However, this was intended mostly to ease transliteration between Python and languages where assignment is directly supported in if
or while
. If you have "hundreds" of such check-and-return in a cascade, it's much better to do something completely different:
hundreds = isBig, isSmall, isJuicy, isBlah, ...
for predicate in hundreds:
result = predicate(y)
if result: return result
or even something like
return next(x for x in (f(y) for f in hundreds) if x)
if it's OK to get a StopIteration exception if no predicate is satisfied, or
return next((x for x in (f(y) for f in hundreds) if x)), None)
if None
is the proper return value when no predicate is satisfied, etc.
Almost invariably, using (or even wishing for;-) the Holder
trick/non-idiom is a "design smell" which suggests looking for a different and more Pythonic approach -- the one case where Holder
is justified is exactly the special case for which I designed it, i.e., the case where you want to keep close correspondence between the Python code and some non-Python (you're transliterating a reference algorithm in Python and want it working first before refactoring it into a more Pythonic form, or you're writing Python as a prototype that will be transliterated into C++, C#, Java, etc, once it's working effectively).
Starting Python 3.8
, and the introduction of assignment expressions (PEP 572) (:=
operator), it's now possible to capture the condition value (isBig(y)
) as a variable (x
) in order to re-use it within the body of the condition:
if x := isBig(y): return x