-1

In C++ you can always pass something as reference and anything that happens within the callee would be known to caller by just examining the referenced variable.

Imagine this scenario:

def x():
   a = f()
   print(a)

def f():
   return "hello"

What I want is add a boolean flag that returns from f to x. There are several ways to do that:

  1. make f return a tuple (str,bool)
  2. pass a reference to a boolean variable into f

option 1 is currently not possible since there are many callers to f() and I cant change them to accept tuple as return value, so it must stay as it is.

option 2 is not possible since boolean argument is immutable (as I've learned recently).

Only f can calculate the boolean value, and x needs to know about it.

Is there any good way to achieve that? Looking for something that is not bad practice in Python coding in general.

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
Itai Bar
  • 747
  • 5
  • 14
  • 1
    What is the Boolean flag for? – Fred Larson Jun 01 '22 at 20:40
  • You can pass in a list of bools and modify the element of the list directly. e.g. b[0]=True where you passed list b into the function. – RufusVS Jun 01 '22 at 20:41
  • 3
    Could you elaborate why you cant change caller to accept tuple as value? – Ach113 Jun 01 '22 at 20:41
  • Especially since you'd have to change all the callers to pass the Boolean flag reference you're proposing. – Fred Larson Jun 01 '22 at 20:42
  • I think many of these would be answered if we had a [Minimal Reproducible Example](https://stackoverflow.com/help/minimal-reproducible-example) – BeRT2me Jun 01 '22 at 20:42
  • 1
    Please don't [re-post](https://stackoverflow.com/q/72467392/3001761). This still lacks any context as to why you actually want to do this, which means it's impossible to say what the right answer actually is. – jonrsharpe Jun 01 '22 at 20:43
  • I think you might rethink all the code, but you could patch it (not recommended... ) pass a list with the flag `[flag]` then the list will mutate – Ulises Bussi Jun 01 '22 at 20:43
  • @FredLarson I can just pass an argument with None default value, so other callers wont notice the change. there are many callers expecting an ORM object return value, if I return (ORM object,bool) value, would they work the same? I cant change them to accept something else beside ORM object – Itai Bar Jun 01 '22 at 20:44
  • You could also put all your functions inside a class and use `self.flag = True` to set the flag without having to return anything. This would also be accessible to all methods within the class – Ach113 Jun 01 '22 at 20:44
  • >{looking for something that is no bad practice in python coding in general} The idiomatic ("Pythonic") way would be to change the function to return a tuple. If the function is prone to changing the things that it returns and you don't want to break callers, maybe consider returning a record (like a `dataclass`) - something like a Parameter Object, but for a return value? – decorator-factory Jun 01 '22 at 20:47

1 Answers1

1

The option that's closest to passing a pointer/reference into f would be to pass it a mutable object, like a list:

def f(ok=None):
    if isinstance(ok, list):
        ok.append(True)
    return "hello"

def x():
    ok = []
    a = f(ok)
    print(a, ok.pop())

But the better solution IMO would be to return a tuple, and refactor that behavior into a new function so that you're sharing code without disturbing the existing API:

def f_with_flag():
    return "hello", True

def f():
    return f_with_flag()[0]

def x():
    a, ok = f_with_flag()
    print(a, ok)
Samwise
  • 68,105
  • 3
  • 30
  • 44