Global scope variable unchanging in python

2019-08-29 12:06发布

问题:

In this code

money = .3

Things = ["Nothing"]

def main():
    print "go to buy things"
    print "Current Money %s" % (money)
    print "Things you have:"
    for item in Things:
        print item
    wait = raw_input()
    buythings(money)


def buythings(money):
    print "Type Buy to buy things"
    buy = raw_input()
    if buy == "buy":
        money = money - .3
        Things.append("Things")
        main()
    else:
        print "you bought nothing"
        print ""
        main()

Why after buying the things does the money not go down? This has been a problem to me for a while now and I cant seem to understand how the scope works in this situation.

回答1:

The global variable money is shadowed by the function parameter money in buythings(money) function. You should remove the parameter for it to work:

def main():
    global money
    global Things
    ...

def buythings():
    global money
    global Things
    ...

However, A better approach, as alfasin pointed out, would be passing money and Things as parameters to both functions and not using global keyword at all:

def main(money, things):
    ...
    for item in things:
        print item
    wait = raw_input()
    buythings(money, things)


def buythings(money, things):
    ...
    if buy == "buy":
        money = money - .3
        Things.append("Things")
        main(money, things)
    else:
        ...
        main(money, things)

>>> money = .3
>>> Things = ["Nothing"]
>>> main(money, Things)

Hope this helps.



回答2:

You can use a global variable in other functions by declaring it as global in each function that assigns to it:

money = 0

def set_money_to_one():
    global money    # Needed to modify global copy of money
    money = 1

def print_money():
    print money     # No need for global declaration to read value of money

set_money_to_one()
print_money()       # Prints 1

In your case :

def buythings():
    global money

Python wants to make sure that you really know what you're playing with by explicitly requiring the global keyword.