首页 > 解决方案 > Completely confused on using global variables using global statement

问题描述

The following set of code completely relies on global variables:

SwordImpact = 1
SwordCrit = 0
SwordSwingSpeed = 2
SDCost = 1.99
SCCost = 4.99
SSSCost = 2.99
Gold = 10.0
inventory = []
Location = 'Town Center'


def Shop():
    global Gold
    global inventory
    global SDCost
    global SCCost
    global SSSCost
    global SwordImpact
    global SwordCrit
    global SwordSwingSpeed
    if Location == 'Town Center':
        Buy = input('Catalog:\nA - Health potion (5.00)\nB - Apple (1.00)\nC - Upgrade Sword (Varies)\nD - Regen potion (7.00)\n---|')
        if Buy == 'A':
            if Gold > 4.99:
                Gold = Gold - 4.99
                inventory.append('Health potion')
                print('Item bought.')
            else:
                print('Not Enough Gold.')
        if Buy == 'B':
            if Gold > 0.99:
                Gold = Gold - 0.99
                inventory.append('Apple')
                print('Item bought.')
            else:
                print('Not Enough Gold.')
        if Buy == 'C':
            Upgrade = input('Select Upgrade:\nA - Sword Damage (2.00 - (increases by 2 each upgrade))\nB - SwordCrit (5.00 (increases by 3 each upgrade))\nC - Sword Swing Speed (3.00 (Increases by 3 each upgrade))\n---|')
            if Upgrade == 'A':
                verify = input('Are you sure you want to pay ' + str(SDCost) + ' for this upgrade?\nA - Yes\nAnything else - No\n---|')
                if verify == 'A':
                    if int(Gold) > int(SDCost):
                        Gold = int(Gold) - int(SDCost)
                        SDCost = int(SDCost) + 2
                        SwordImpact = SwordImpact + 1
                    else:
                        print('Not enough gold.')
            if Upgrade == 'B':
                verify = input('Are you sure you want to pay ' + str(SCCost) + ' for this upgrade?\nA - Yes\nAnything else - No\n---|')
                if verify == 'A':
                    if int(Gold) > int(SCCost):
                        Gold = int(Gold) - int(SCCost)
                        SCCost = int(SCCost) + 3
                        SwordCrit = SwordCrit + 1.5
                    else:
                        print('Not enough gold.')
            if Upgrade == 'C':
                verify = input('Are you sure you want to pay ' + str(SSSCost) + ' for this upgrade?\nA - Yes\nAnything else - No\n---|')
                if verify == 'A':
                    if int(Gold) > int(SSSCost):
                        Gold = int(Gold) - int(SSSCost)
                        SSSCost = int(SSSCost) + 3
                        SwordSwingSpeed = SwordSwingSpeed + 1.0
                    else:
                        print('Not enough gold.')
        if Buy == 'D':
            if Gold > 6.99:
                Gold = Gold - 6.99
                inventory.append('Regen potion')
                print('Item bought.')
            else:
                print('Not Enough Gold.')
    else:
        print('You need to be in Town Center.')

But I have a major problem with this set of code: When I go to check the variables Gold and Inventory, they have not changed after going through and 'buying' something. Can I get a better way to do this or a better use of the 'global' statement?

标签: pythonglobal

解决方案


In your code, there appears to be no specific reason for the use of global variables: since there is precisely one function that accesses them, they would as well be defined inside the function.

I suspect, however, that there is other code we do not know about.

When you say the value of the variables has not changed, it would be as well to show the code you are using to verify that. Clearly at the start of every run the value of Gold begins at 10.0, and should change when things are bought.

If there are many functions that need to access the same state variables you would most likely find it less confusing to keep them all as attributes of some state object, which is then passed in to each function to allow it to access and modify the state, which would now be explicitly available inside each game function. For example, calling the state 'player', since it appears that each player will need their own if there are multiple players, you might write:

class Player:
    def __init__(self):
        self.SwordImpact = 1
        self.SwordCrit = 0
        self.SwordSwingSpeed = 2
        self.SDCost = 1.99
        self.SCCost = 4.99
        self.SSSCost = 2.99
        self.Gold = 10.0
        self.inventory = []
        self.Location = 'Town Center'

Your code would then follow:

def Shop(player):
    if player.Location == 'Town Center':
        Buy = input('Catalog:\nA - Health potion (5.00)\nB - Apple (1.00)\nC - Upgrade Sword (Varies)\nD - Regen potion (7.00)\n---|')
        if Buy == 'A':
            if player.Gold > 4.99:
                player.Gold -=  4.99
                player.inventory.append('Health potion')
                print('Item bought.')
            else:
                print('Not Enough Gold.')

and so on - note that the player object now stores the various things that can change.

In general the use of global variables is discouraged because it makes your code non-modular: values that functions require should be passed as arguments to method calls rather than being held in specific global variables.


推荐阅读