0

I'm extremely new to python, so I apologize if this is a simple question, I'm creating a program where I need to share a global variable across multiple files. I have a file called settings.py that looks like this:

def init():
    global BACKPACK
    global SURVIVAL_TOOLS

    BACKPACK = {}
    SURVIVAL_TOOLS = {}

I import those settings into another file called battle.py and prepare.py:

from settings import init
# battle.py #
def win_battle(animal):
    print "You do one final slash and the {} goes limp." \
          " You pick it up and start walking back to camp.".format(animal)
    init.SURVIVAL_TOOLS['meat'] = 1
    if 'camp' in init.SURVIVAL_TOOLS:
        return_to_camp()
    else:
        options = ['create a fire', 'create a camp']
        for opt in options:
            print "TEST"  # TODO: FINISH THIS METHOD

from settings import init

def gather_gear(player):
    # prepare.py #
    """
    Gather your gear from a set list of items you have available
    :type player: String
    """
    print formatter()
    print "{}! Shouts Jack as he runs towards you." \
          " Do you wanna go Hiking this weekend?" \
          " You ponder this for a second." \
          " What the hell, you think." \
          " Can't be any worse then last time." \
          " Sure, Jack! You say enthusiastically." \
          " Just let me get some things prepared.\n".format(player)

    options = {  # All the items that are available to you before you leave
        'fire starter': 1,
        'matches': randint(1, 5),  # Uses random integers as the value
        'flash light': 1,
        'sleeping bag': 1,
        'canteen cup': 1,
        'dried foods': randint(2, 6),
        'shovel': 1,
        'knife': 1,
        'pair of socks': randint(2, 10),
        'granola bars': randint(2, 5),
        'machete': 1,
        'bottle of whiskey': 1,
        'heavy jacket': 1,
        'tinder pieces': randint(3, 5)
    }

    for key in options:
        print "You have {} {}".format(options[key], key)  # Print out all your items and make it look pretty

    count = 3
    num_in_pack = 0
    print '\n'
    while count != 0:
        item = raw_input("What would you like to take with you? Choose {} items one at a time: ".format(str(count))).lower()
        if item in options and item not in init.BACKPACK:  # As long as the item is available you can use it
            init.BACKPACK[item] = options[item]  # Add the item value to your backpack constant
            count -= 1
            print "You throw a {} in your backpack".format(item)
            num_in_pack += 1
            if num_in_pack == 3:  # If you have three items, lets begin!
                print "Your backpack is now full."
                start_adventure(player)
        else:
            print "Can't bring that item."

    return init.BACKPACK

However I get a warning in my IDE that:

Cannot find reference 'SURVIVAL_TOOLS' in 'function' less... (Ctrl+F1 Alt+T) This inspection detects names that should resolve but don't. Due to dynamic dispatch and duck typing, this is possible in a limited but useful number of cases. Top-level and class-level items are supported better than instance items.

And when this program is run I get:

Traceback (most recent call last):
  File "game.py", line 1, in <module>
    from prepare import *
  File "C:\Users\thomas_j_perkins\bin\python\game\prepare.py", line 1, in <modul
e>
    from game import *
  File "C:\Users\thomas_j_perkins\bin\python\game\game.py", line 2, in <module>
    from choices import *
  File "C:\Users\thomas_j_perkins\bin\python\game\choices.py", line 3, in <modul
e>
    from prepare import BACKPACK
ImportError: cannot import name BACKPACK

I got the idea of moving all my constants to a single file from this question

So my question is, why am I unable to use the constant variables that I have created in the settings.py file?


EDIT:

I attempted to do init().BACKPACK and am now getting the error:

Traceback (most recent call last):
  File "game.py", line 94, in <module>
    welcome_screen()
  File "game.py", line 85, in welcome_screen
    gather_gear(player_name)
  File "C:\Users\thomas_j_perkins\bin\python\game\prepare.py", line 45, in gathe
r_gear
    if item in options and item not in init().BACKPACK:  # As long as the item i
s available you can use it
AttributeError: 'NoneType' object has no attribute 'BACKPACK'
Community
  • 1
  • 1

1 Answers1

0

When you do global BACKPACK; BACKPACK = {}, you are creating a module attribute called BACKPACK. To access it, change from settings import init to import settings. This will allow you to use all the module attributes of settings in your code:

settings.SURVIVAL_TOOLS['meat'] = 1

You also need to make sure that settings.init is called once in your program. You can either call it somewhere in your code, or better yet, modify settings.py to look like this:

BACKPACK = {}
SURVIVAL_TOOLS = {}

No function definitions, no globals. This code will get run the first time the module is imported anywhere. Next time is is imported, the dicts will not be modified.

Mad Physicist
  • 107,652
  • 25
  • 181
  • 264