Let a module file use a global variable?

2019-09-12 08:48发布

问题:

Forgive me if this is just a super easy solution as I am pretty new to Python. Right now I'm trying to make a basic video game, and to save space I decided to make a module for a combat encounter -- so that all I have to do when writing the code for each encounter is run the function in that module, only having to write the unique variables of the enemy. However, the code needs to know things like the player's HP, or what kind of weapon the player has. I tried putting global before the variables in the function module, but of course it doesn't work, as that's referencing global variables in the module, not the main game file. Or is there another way to go about this? If you need me to enclose my code, I will gladly do so.

Edit: Heres the code, in the module (called combat). What I want it to do is the main file's code will just say:

combat.combat(3, "mysterious creature", 12, 2, 4, 3, "claws", 5, 0)

Which, based off my shallow understanding, is how i edit the variables for each oppoent, its from this line in the module file.

def combat(enemylevel, enemyname, enemyhp, enemydefense, enemystrength,
           enemyattack, enemyweaponattack, enemygp, run):

Based off you guys' confusion I'm guessing I'm doing something pretty basic wrong. Forgive my (most likely) cringey and ineffecient code-writing:

import random
import math
def combat(enemylevel, enemyname, enemyhp, enemydefense, enemystrength, 
           enemyattack, enemyweaponattack, enemygp, run):
    global xp
    global hp
    global maxhp
    global gp
    global weapon_attack
    global weapon
    levelandname = "level" , enemylevel, enemyname
    print("You draw your weapon and prepare for battle. You are fighting a",
          levelandname, ".")
    while enemyhp > 0:
        if enemyhp > 0:
            print()
            attackorrun = input("Do you wish to attack or run? ")
            if attackorrun == "attack" or "a":
                print("You" , weapon_attack , "your" , weapon, "at the",
                      enemyname) # this is where the first error happens,
                                 # says weapon_attack isn't defined.
                attackroll = random.randint(1, 20)
                attackroll = (attackroll+(math.floor(attack/2)))

I'm probably still leaving something unclear, feel free to tell me to do something else or ask me something.

回答1:

Using large numbers of global variables can get messy. It doesn't provide you much flexibility, and as you're discovering, its hard to access those variables from other modules.

Many programmers will avoid using the global statement in a function, any data the function needs should be provided by other means.

Using container objects might be a good start, keeping related variables together, perhaps in a dictionary. You could pass an enemy dict (with hp, defense, strength etc.) and a player dict (xp, hp, weapon etc.) in to your function. That would give you access to those values in the function, and the function would even be able to modify those values (because you would be passing an object reference).

enemy = {'hp': 100, 'weapon': 'axe', 'strength': 50}
player = {'xp': 22, 'hp': 150, 'weapon': 'sword'}
def combat(player, enemy):
    #calculate results of combat
    player['hp'] = player['hp'] - damage

Another strategy might be to use classes. Classes are object definitions that can contain functions and variables. You can instantiate multiple instances of your class. An Enemy object (instance of an Enemy class) for example would contain an enemy hp variable, and functions that modify it during combat.