Pergunta

I'm quite new to programming and I keep reading everywhere "using methods to change global variables is not good coding. Use very little global variables and definitely don't change them". I can't seem to find a good explanation of why or what should be done.

Lets say I want to have some sort of a game. And it has variable health=100. Now I figured this should be a global variable and not inside a class/object, but that would also mean I would need to adjust it and so on by doing something like:

def minushealth():
    global health
    health -= 20

I can't really seem to figure this out and maybe there is just something simple I don't know here.

Foi útil?

Solução

You could make health an explicit argument to and return value from the function:

def minus_health(health):
   return health - 20

then assign the return value when you call it:

health = minus_health(health)

Even better, get rid of the "magic number" with an optional second argument:

def minus_health(health, amount=20):
   return health - amount 

Note that you can now test minus_health like:

assert minus_health(100) == 80

whereas if you implemented with global, you would have to do:

health = 100
minus_health()
assert health == 80

It might not seem like a huge problem in this simple example, but as your program gets more complex you have much more setup and tear-down to do, whereas a well-isolated function will still be effectively testable in one line.

Outras dicas

jonrsharpe's answer is on point.

But for a game type answer you'd be better off using the class/attribute solution which would look like:

player_object.minus_health()

Where minus_health would look like:

class Player(object):
    def __init__(self):
        __health = 100

    def minus_health(self):
        self.__health -= 20

Of course this doesn't take into account if the health goes below 0, etc. But you should get the idea. This way allows all "Players" to have separate health attributes.

The Player class shown in another answer is probably going to be where you end up, but just an explanation of arguments to a function, you can only modify arguments that are mutable. In your specify case, an approach similar to the Player class, but simpler, is to manage your state in a dict and then pass that dict into the function to modify an attribute:

def minus_health(entity, amount=-20):
    entity['health']+=amount

# Use like so
player = dict(name='John', health=100)
minus_health(player)

lists and objects are also mutable and will work in a similar way, i.e. their contents can be modified inside the function.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top