1

I am trying to write a python function with an optional argument tr, if this argument was not specified, then I want to take a global variable instead.

DEF_tARGET = "UserA"
def display_target(tr=DEF_TARGET):
    print(tr)

The problem is that when I change the global variable somewhere in my program, then call the function with no tr argument, the function is still taking the initial value (when the function was declared) of the global variable. See the example below:

DEF_TARGET = "UserA"
def display_target(tr=DEF_TARGET):
    print(f"target is {tr}")

display_target("UserB")     # prints UserB

DEF_TARGET = "UserB"
display_target()

Output

target is UserA

Expected

target is UserB

I could declare the function as below, but I was looking for a better approach

def display_target(tr=None):
    if not tr:
        tr = DEF_TARGET
    print(f"target is {tr}")
6
  • 1
    Don't use if not tr. Use if tr is None. Lots of things other than None evaluate to false (False, 0, "", etc.) Commented Jul 2, 2020 at 10:00
  • 2
    Using solution based upon if tr is None is the standard answer for global as default parameter Commented Jul 2, 2020 at 10:02
  • Thank you, so the default variable is only evaluated and set once at the declaration of the function. Commented Jul 2, 2020 at 10:10
  • @TomKarzes Thank you for this note. I actually uses tr = tr or DEF_TARGET, which does the same. Commented Jul 2, 2020 at 10:15
  • @Shadowfax Yes, that has the exact same problem: If tr is False or 0 or "" or anything else that evaluates to False, you'll ignore it and use DEF_TARGET instead. Change it to tr = DEF_TARGET if tr is None else tr if you want a one-line assignment. Commented Jul 2, 2020 at 10:17

1 Answer 1

2

The behaviour in python when defining your function is the following:

  • Create a function object
  • Compile your code and store it in the object
  • Make sure everything (e.g. variables) needed to run the code will by available when you want to launch the function

In the case of the defaults arguments they are stored either in the attribute __defaults__ or in __kwdefaults__. And in the case of the basic types like strings, char, int or float they are copied to this location.

So the definitive response is no. You cannot force python to create a reference for you here. But if you just want to make you code prettier, that is possible:

def display_target(tr=None):
    tr = tr or DEF_TARGET
    print(f"target is {tr}")
Sign up to request clarification or add additional context in comments.

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.