0

In python want to do something like this:

def func(*args, flag):
    do something 
    if cond A:
        flag="some A" 
    else:
        flag="some B"

Then I found the flag passed is always unchanged.

If I change the flag to be a list, then yes it works but is ugly. What is the proper way to achieve the above?

JP Zhang
  • 767
  • 1
  • 7
  • 27
  • 1
    Return the flag. – j1-lee Dec 20 '21 at 06:23
  • Python **never** supports call by reference, which is the semantics you are expecting. Indeed, most modern languages do not (C# does, though). – juanpa.arrivillaga Dec 20 '21 at 06:24
  • @j1-lee I wish things could be this simple. But in my program I have to return something other than the flag. – JP Zhang Dec 20 '21 at 06:25
  • @j1-lee well, importantly, you'd need to call it like `flag = func(*args, flag)`, i.e. *assign the resulting value to the variable in the caller* – juanpa.arrivillaga Dec 20 '21 at 06:25
  • 1
    @JPZhang Then return something _and_ the flag. – j1-lee Dec 20 '21 at 06:26
  • You can return more than one thing: `foo, flag = func()`. – deceze Dec 20 '21 at 06:26
  • @deceze to be absurdly pedantic, you can return an *iterable* of things, and unpack that in the caller :) – juanpa.arrivillaga Dec 20 '21 at 06:26
  • @deceze Yeah I know this workaround. I wonder what are other possibilities. – JP Zhang Dec 20 '21 at 06:27
  • 1
    The other alternative is passing in a mutable object and mutating that object. e.g. `class Flag: pass` then`flag = Flag()` then something lie `flag.value = whatever` in the function, although this is not ideal (functions mutating their inputs is usually not the greatest approach, but as long as it is clearly documented it is accetable) – juanpa.arrivillaga Dec 20 '21 at 06:27
  • @juanpa …more than one thing, *wrapped in an iterable*. Sorry, lost carrier connection there. – deceze Dec 20 '21 at 06:28
  • Also I think this question shouldn't be closed. Yes it is related to "passing by reference". But it's not just about passing by reference. It's about using passing by reference to achieve flag functionality. If two are question are really the same, why couldn't I easily find my answer earlier on? – JP Zhang Dec 20 '21 at 06:36
  • @juanpa.arrivillaga In Python everything isn't an object? And the difference lies in mutable or immutable? In my previous experiment I set the outside variable to be a `None` and passed it in expecting it to be changed to a str but it didn't. – JP Zhang Dec 20 '21 at 06:44
  • @JPZhang Yes, everything is an object in Python. I'm not sure *why* you expected a variable in the caller to be affected by assignment in a function, i.e. pass by reference semantics, **which python never supports**. None of that has anything to do with mutable or immutable, you can't pass *anything by reference*. The semantics are simply not supported by the language. – juanpa.arrivillaga Dec 20 '21 at 06:48
  • 1
    " It's about using passing by reference to achieve flag functionality." The linked duplicate explains that Python **never** passes anything by reference, and alternatives to achieve the same effect using Python's evaluation strategy. It is totally appropriate. I don't think this is a bad question, it just already has an answer. – juanpa.arrivillaga Dec 20 '21 at 06:48
  • Note, there are a lot of terrible, misleading answers there. The accepted answer, however, is totally correct. – juanpa.arrivillaga Dec 20 '21 at 06:56

0 Answers0