简体   繁体   中英

Accessing python variables from other python modules, which are inside a function

I'm pretty new to python, and I am have a problem in one of my projects that I can't get over with, no matter how many articles I read.

So I have two.py files.

The First One: (first.py)

from second import *
function(10, 30)
print(answer)

The Second One: (second.py)

def function(one, two):
     global answer
     answer = one + two

So second.py creates a global variable, and first.py imports second.py, and tries to print out my_var. But for some reason I always get this error message:

Traceback (most recent call last):
  File "first.py", line 3, in <module>
    print(answer)
AttributeError: module 'second' has no attribute 'answer'

...

May I ask for some help, please? I was really trying, but for the sake of Lord I could not figure it out!

It would be better if you made your function return a the value:

def function(one, two):
     answer = one + two
     return answer

then you could setup your other file like this:

from second import function
answer = function(10, 30)
print(answer)

also function is a terrible name for a function call it something descriptive

There is no global variable definition.
Replace second.py:

answer = None

def function(one, two):
    global answer
    answer = one + two

I believe that this question is answered in another way, you can refer to this question . You have defined global answer inside a function (not outside the function and without assigning any value for it), so at import time, this variable, even with its global nature, is not declared yet. without too much details about how to refactor your solution, you just need first.py to be written that way:

import second
second.function(10, 30)
print(second.answer)

This way, you have not changed second.py , and also imported the global variable as you wanted.

well, let me explain what happens when you import something from one script to another. when, you write:

from second import *

it copies the names from second.py into the namespace of first.py . So, if you reassign any variable of second.py (in you case answer ) in first.py , the change will only be done in first.py , not in second.py . So, I hope you've understood that, first.py's answer and second.py's answer each of them have occupied different memory location. For your understanding I've written a test, read the code and see the output, you'll understand what's happen when you import something:

second.py

answer = 0 # you've to declare "answer" as as global variable
           # this is one mistake you've done in your code

def function(one, two):
    global answer
    answer = one + two

def print_answer_in_second():
    print("in second: {}".format(answer))

first.py :

from second import *

print("in first: {}".format(answer))
print_answer_in_second()

function(10, 30) # calling function() to change answer value in second.py

print("in first: {}".format(answer))
print_answer_in_second()

answer = 100 + 800; # changing answer value in first.py

print("in first: {}".format(answer))
print_answer_in_second()

output :

in first: 0
in second: 0
in first: 0
in second: 40
in first: 900
in second: 40

I hope, you get the idea around import.

Now, how can we solve this problem beautifully? Global variables are essential part of a language, the programming world can't run without the existence of globals . But globals also create problems. It's hard to maintain globals . So, what would be the best practice with globals ?

Well, if you're developing an app or any project, the best practice to put the globals of your app or project in a single file, so that, we may easily find them and change their values. Let's call our global file glob.py . Here's the code for glob.py :

glob.py:

# declaring global answer
answer = 0

Now, let's declare new_second.py :

new_second.py :

import glob

def function(a, b):
    glob.answer = a + b

def print_answer_in_second():
    print("In second: {}".format(glob.answer))

new_first.py :

import glob

from new_second import function, print_answer_in_second
# note: "import ... from *" is a very bad practice
#       so, avoid use that style of import

function(10, 30)

print("In first: {}".format(glob.answer))
print_answer_in_second()

output :

In first: 40
In second: 40

I hope, you get the idea of how to use globals properly without affecting too much other parts of your code.

Use return . If you want to return multiple answers, try the following.

first.py:

from second import function

ans1, ans2 = function(1, 2, 3)
print(ans1, ans2) # 3 5

second.py:

def function(one, two, three):
    answer1 = one + two
    answer2 = two + three
    return answer1, answer2

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM