简体   繁体   中英

How to define a boolean parameter in Python

I have defined a function that would print a specific string depending on its value. However, I get an error message saying that global name 'must_print' is not defined .

This is the code I have:

def myfunction(must_print):
    must_print = True
    if bool(must_print) == True:
        print("Done")
    elif bool(must_print) == False:
        print("Change value")

if __name__ == "__main__":
    myfunction(must_print)

Do you know why I'm getting this error?

The parameter named "must_print" in the definition is completely unrelated to the function call's argument named "must_print".

The following code is equivalent to yours:

def myfunction(x):
    x = True
    if bool(x) == True:
        print("Done")
    elif bool(x) == False:
        print("Change value")

if __name__ == "__main__":
    myfunction(must_print)

When Python executes the code, it first defines the function, and then tries to execute myfunction(must_print) .
But at that point, nothing called "must_print" has been defined.

The parameter name is a way for the function you're defining to refer to the value it gets passed when it is called – it doesn't matter to the function how that value is spelled by the code that calls the function, and the name of the parameter doesn't matter to the calling code.

This means that you can understand the function definition in isolation, so let's do that.

def myfunction(must_print):
    # Replace whatever value must_print had with True
    must_print = True
    # Convert must_print, which has a boolean value, into a boolean, and compare it to True
    if bool(must_print) == True:
        print("Done")
    # Convert must_print, which has a boolean value, into a boolean, and compare it to False
    elif bool(must_print) == False:
        print("Change value")

Replacing the parameter's value with a different one makes the parameter pointless – when you get to if it will be True regardless of what you passed, and myfunction("Vacation") will do the same as myfunction(False) .

Remove that assignment:

def myfunction(must_print):
    # Convert must_print into a boolean, and compare it to True
    if bool(must_print) == True:
        print("Done")
    # Convert must_print into a boolean, and compare it to False
    elif bool(must_print) == False:
        print("Change value")

But bool(must_print) must be either True or False , so you only need else and one condition:

def myfunction(must_print):
    # Convert must_print into a boolean, and compare it to True
    if bool(must_print) == True:
        print("Done")
    else:
        print("Change value")

Now, if an expression e is a boolean, e == True is the same as e .
( True == True is True , and False == True is False .)
So we can simplify some more:

def myfunction(must_print):
    # Convert must_print into a boolean
    if bool(must_print):
        print("Done")
    else:
        print("Change value")

And further, any Python value is treated as a truth value by if .
That is, if bool(e) is the same as if e :

def myfunction(must_print):
    if must_print:
        print("Done")
    else:
        print("Change value")

Now all that remains is to call the function, passing it a suitable argument:

if __name__ == "__main__":
    myfunction(True)

There are lots of things need to optimize in your code. Please have a look at this sample:

def myfunction(must_print):
    if must_print:
        print("Done")
    else:
        print("Change value")

if __name__ == "__main__":
    myfunction(True)

you should value the global limit.

Code:

must_print = True    

def myfunction(must_print):
    global must_print

    must_print = True
    if bool(must_print) == True:
        print("Done")
    elif bool(must_print) == False:
        print("Change value")

if __name__ == "__main__":
    myfunction(must_print)

Output:

Done

You're confusing a few things, which is easy to do when you get started with functions.

You don't need a global variable for what you're doing, but at some point, you should read Use of "global" keyword in Python to understand more about globals.

In your first 6 lines, where you define the function myfunction , you're telling python that there is one parameter, named must_print . This parameter is local within the function, and what you set it to only exists inside that function.

You can invoke the function in several different ways:

m_p = True
myfunction(m_p)

or

myfunction(True)

or even

myfunction(must_print=True)

They all boil down to the same thing: telling python to call the function myfunction , and pass into the first parameter (which is named must_print ), the value True. Then python invokes the function, making a local variable named must_print . (Incidentally, in your first line of the function, you set the variable to True, thereby disregarding whatever input is given. Consequently, myfunction(True) and myfunction(False) will have the same results right now.)

The key point is that you pass something else when you invoke the function - either a variable or a constant term. (In the third case, you're explicitly telling it that the argument named must_print is set to be True. In that case, after the = , there's either a constant or a variable. The first two cases simply set the first argument to True while the last one specifies the argument by name.) Outside of the function myfunction , the variable must_print is not defined, so python expects it to be somewhere in the global scope.

Note, to reduce confusion, I'm deliberately avoiding this:

must_print = True
myfunction(must_print)

This is perfectly valid code, but it's confusing. In that case, you have a variable local to your if clause that you use to set the argument you pass into the function, which then has a variable local to the function, of the same name. That's much more confusing, so I started with the m_p variable, instead.

Some good reading on python scope is Short Description of the Scoping Rules? , particularly these two answers: https://stackoverflow.com/a/34094235/1404311 , https://stackoverflow.com/a/292002/1404311

Edit, based on comment :

def myfunction(must_print=True) and myfunction(must_print=True) does two entirely different things.

The keyword def is where you define a function. In a function definition, must_print=True says that you have a variable named must_print whose default value is True. Thus, inside the function, whether you do myfunction(True) or just myfunction() , there will be a parameter named must_print whose value is True. Only if you explicitly set it to some other value (such as myfunction(False) will the variable of must_print not be True.

In the second version, you're explicitly naming the argument. When you only have one argument, it's not really meaningful, so try this:

def foo(arg1=8, arg2='hello', arg3=True):
    print(arg1, arg2, arg3)

You can then do foo() , which will print "8 hello True". Or you can do foo(7) , which will explicitly set arg1 and use the defaults for arg2 and arg3, and print "7 hello True". Or foo(6, 'goodbye') prints "6 goodbye True", or foo(5, 'whatever', False) , will print "5 whatever False". But how can you use defaults and only change the last argument? That's where named parameters come in. Try foo(arg3=False) , and the output will be "8 hello False".

The best way to learn is by doing. Experiment with small functions like this one, inside the python interpreter. You'll get the hang of it quickly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM