HunBurry
HunBurry

Reputation: 133

Manipulating and Importing Global Variables Across Multiple Files

I am trying to create a program in Python, and have all of my functions declared in a file called "functions.py." In the "main.py" file, I use

from functions import setup

to call the "setup" function. However, whenever I run the file, I have an error that "name" does not exist. I am not sure what the error is. I have done some reading about using global variables across files, and that's how I came up with "functions.name," which also does not work. I am not really looking for a solution per se, but really want to know what the best way to go about importing and manipulating variables across files would be, because the code I have attached is only a very small segment of the real setup function and main code.

functions.py

def setup():
#Sets up the player's stats.
    global name
    name = input("What is your name? ").capitalize()

main.py

setup()    
print ("Welcome " + functions.name + ".")

Upvotes: 0

Views: 148

Answers (3)

ikom
ikom

Reputation: 166

One way to share variables across multiple scripts is to keep them in a separate script that does nothing other than keeping those variables. You can refer to each variable by referring myscript.myvar. It's similar to references to class variables (Myclass.classvar / self.classvar) or imported functions (e.g. np.array).

An example:

params.py

# Variable declarations with some default value.
name = ''
somevar = 0
somevar2 = None

functions.py

import params

def setup():
#Sets up the player's stats.
    params.name = input("What is your name? ").capitalize()

main.py

import params
from functions import setup
setup()    
print ("Welcome " + params.name + ".")

What is your name? morble

Welcome Morble.

You've almost done this but are missing the 'unwrapped' variable declaration. It might also work if you declare name in function, but outside any def and import the script in its entirety, but I think the 'recommended' approach is to use a separate script. The difference in the above approach is that params keeps the references to those variables alive. In your function, name is lost when the function returns because there are no more references to it.

Upvotes: 1

Prune
Prune

Reputation: 77875

If you want to have a package-level variable, you have to create it at the package level:

name = ""

def setup():
#Sets up the player's stats.
    global name
    name = input("What is your name? ").capitalize()

Now you can access the variable:

>>> from functions import setup
>>> setup()
What is your name? Ivan
>>> functions.name
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'functions' is not defined
>>> import functions
>>> functions.name
'Ivan'
>>> 

Upvotes: 0

Robᵩ
Robᵩ

Reputation: 168706

The solution per se is to change how your import works:

import functions
functions.setup()
print(Welcome " + functions.name + ".")

However I fear that if you pursue this approach, your multi-file program will be just as confusing as your single-file program was.

The broader solution is to avoid global variables when you can. Perhaps setup can return whatever it creates and then its caller can decide what to do with it:

def setup():
    return input("What is your name? ").capitalize()

and

name = functions.setup()
print("Welcome " + name + ".")

Or, if setup() has more work to do than just discover the player's name, try this:

# functions.py
class Player:
    # Fill this in later as you refine your design
    pass

def setup():
    player = Player()
    player.name = input("What is your name? ").capitalize()
    # player.score = ...
    # player.charm = ...
    # etc
    return player

and

import functions
player = functions.setup()
print("Welcome " + player.name + ".")

Upvotes: 1

Related Questions