I have 2 files:
Main.py
from test import test
def main():
sol = 'hello'
if test() == sol:
print('Yes')
else:
print('No')
test.py
def test():
return 'hello'
Is there a way to access the sol variable in my test function which is in another file? I'd like to do something like this:
def test():
return sol
This way it's always the same as the variable in Main.py. I tried a solution which is mentioned on Python extract variables from an imported file but it didn't work for me. Thank you for any help
Edit: I'd like to do it without changing the Main.py file
Since sol isn't defined in the function you will need to declare it as a global function so it can be used in the function. Change test.pyto the following...
test():
global sol
return sol
Hope that helps.
If sol is a constant (i.e. a variable which will not change during the course of the program), then you can put it into a separate file, say var.py, and import it into both main.py and test.py:
from var import sol
BUT what you will be importing is a copy of the variable with the value it had at the time it was imported - any subsequent reassignments will not update the value of sol in test.py and main.py. Because a string is immutable, when you reassign a value to it what you are actually doing is you are reusing the variable name for a new entity.
What you need to do is have your variable in a mutable structure, such as a list or a class, so your var.py will look like this:
class v(object):
sol = 'Hello'
and then in main.py and test.py you can refer to sol using:
from var import v
print(v.sol)
This way, any changes to v.sol will be correctly reflected anywhere class v is imported. A bit cumbersome, but that's how it is in Python.
You can use inspect module to get the sol variable from main function without change anything of main.py. Of course, you need to call main function.
Main.py:
from test import test
def main():
sol = 'hello'
if test() == sol:
print('Yes')
else:
print('No')
main()
test.py:
import inspect
def test():
frame = inspect.currentframe()
sol_from_main = 'default'
try:
sol_from_main = frame.f_back.f_locals['sol'] # line A
except:
print('No sol found')
print(sol_from_main) # this print 'hello'
return sol_from_main
Output:
hello
Yes
Explanation:
From the python doc, we can see next:
frame
f_back | next outer frame object (this frame’s caller)
f_locals | local namespace seen by this frame
So line A get the caller of current function, that is main function, and use f_locals to get all local variables of main function, so it can get the sol value from main. FYI in case you still need it.
Related
I have a global variable that's declared inside a function in the functions.py file and I want to access this global variable in the main.py file. How do I achieve that?
# functions.py
def someFunction():
global someVariable
#main.py
from functions import *
someVariable=0
importing module with * gives access to all variables and functions in the current file. This should be working. Please tell me where you are facing a problem in this.
someVariable is defined in someFunction().
If you haven't called someFunction(), so the someVariable is undefined.
You can do this:
in main.py
#main.py
from functions import *
someFunction()
someVariable = 0
or in functions.py
# functions.py
someVariable = 0
One thing that you can do is intstead of declaring it inside function declare it as function attribute like shown below
# functions.py
def someFunction():
#your code
# main.py
from functions import *
setattr(someFunction,'key_name',0) # this is how u set the value
someVariable = getattr(someFunction,'key_name') # this is how u access it
But if real code is not Possible please give a much clearer example code so that we can help you debug the exact problem
I am trying to find a way to share a variable between multiple python scripts. I have the following code:
b.py
my_variable = []
a.py
from b import my_variable # import the value
def run():
global x
x = my_variable.append("and another string")
print(my_variable)
if __name__ == '__main__':
run()
c.py
import a
print(a.x)
a.py runs just fine without giving any error. However, when I run the c.py file, it gives off the following error:
Traceback (most recent call last):
File "E:/MOmarFarooq/Programming/Projects/Python Projects/Variables across files/c.py", line 2, in
<module>
print(a.x)
AttributeError: module 'a' has no attribute 'x'
What I want the code to do is, print the new value of my_variable after it has been changed in a.py . Is there any way I can do that?
the error occurred because you never called the run function from a.py. The if __name__=='__main__': statement is only satisfied if you are running a.py as a program, not importing it as a module.
So a.py should be
from b import my_variable # import the value
def run():
global x
x = my_variable.append("and another string")
print(my_variable)
run()
Note that x will be set to None because the append function does not return anything. It just appends a value to a list.
You need to call the run() function in your c.py file.
Here's how the code should be:
import a
a.run()
Well, module 'a' does have no attribute 'x'. Module 'a' has a function that creates a variable 'x', but as long as the method isn't called, the attribute isn't there.
You could change file c.py to:
import a
a.run()
print(a.x)
Another solution would be to make sure that the run() function is always called when importing module 'a'. This is currently not the case, because of the line if __name__ == '__main__':.
If you don't want to run the code but only want to make sure the variable exists, just define it in the module. Before the definition of your run() method, just add x = None (or use any other initial value you prefer).
Note, however, that there other problems with your code and that using globals in this way is a really bad programming pattern, which will likely lead to other problems later on. I wonder what you want to achieve. It probably would be a better solution if you could pass x as argument to the run() function instead of referring to a global variable. But that's outside the scope of this question and difficult to answer without more information.
I understand that variables in python are always (?) available in subfunctions.
That is why this works:
def abc():
print(a)
def main():
abc()
pass
if __name__=='__main__':
a = 'a'
main()
However, why does it not work if the definition of ais moved to main()?
def abc():
print(a)
def main():
a = 'a'
abc()
pass
if __name__=='__main__':
main()
It is still defined before it is used and should be available in abc(), right?
No, variables defined in a function are scoped to the function by default. To make it available in abc() you would need to make it global:
def main():
global a
a = 'a'
abc()
As for the 'shadowing' warning, you get it when you redefine names at inner scopes. For example, this code creates a global variable a:
if __name__ == '__main__':
a = 'a'
main()
Now if you do a = 'b' inside main() you are effectively 'shadowing' a from the outer scope by creating a local variable with the same name.
In the first code sample, 'a' is defined as a global variable. Meaning that it can be accessed by any function called after it is instantiated.
In the second code sample, 'a' is defined as a local variable. Meaning that it only exists within the "main" function. If you wanted to pass it into the "abc" function, you would have to explicitly pass that variable. That would look like:
def abc(a):
print(a)
def main():
a = 'a'
abc(a)
pass
if __name__=='__main__':
main()
Variables at the module level of your function are available to read anywhere else in the module. When you do
if __name__=='__main__':
a = 'a'
you are defining a as a module-level variable, hence why you can read it inside abc(). This is similar to why you can see your imports within other functions.
When you define a inside abc(), it's no longer at the module-level and no longer is implicitly readable elsewhere in the module.
As an aside, global variables are usually a bad idea, it's better to pass them around explicitly. See http://wiki.c2.com/?GlobalVariablesAreBad for a good summary of why.
I have a problem with including a function from another file to main executable script. I have too many functions and my main script became too long and hard to manage. So i've decided to move every function to separate file and than attach/include it. I've read nearly any relative post here to resolve my problem but no luck. Let's see:
main_script.py
==================
from folder.another_file import f_fromanotherfile
class my_data:
MDList=[]
work=my_data()
def afunction():
f_fromanotherfile()
return
and
another_file.py
=====================
#In this file i've put just function code
def f_fromanotherfile():
a=[1,2,3,4]
work.MDList=a
return
And this is the error:
line 11, in f_fromanotherfile
work.MDList=a
NameError: global name 'work' is not defined
Help me please
The scope of 'work' is its module, main_script.py, so you cannot access it from another module. Make 'work' an argument of f_fromanotherfile instead:
In another_file.py:
def f_fromanotherfile(work):
# function body stays the same
In main_module.py:
def afunction():
f_fromanotherfile(work)
because in another_file.py
#In this file i've put just function code
def f_fromanotherfile():
a=[1,2,3,4]
work.MDList=a
return
work is not a global variable.And then doing assignment to it can't work.
u should change ur code to: another_file.py
#In this file i've put just function code
def f_fromanotherfile():
global work
a=[1,2,3,4]
work.MDList=a
return
with the global keyword u can say the variable in so-called global scope and do ur assignment.
PS:kind of like the keyword extern in C?
Hi, there.
I have two files:
a.py:
print('in a')
import b
print('var')
VAR = 1
def p():
print('{}, {}'.format(VAR, id(VAR)))
if __name__ == '__main__':
VAR = -1
p()
b.p() # Where does this VAR come from?
b.py:
print('in b')
import a
def p():
a.p()
I don't understand why there're two different VARs, which is supposed to the same.
If I move the 'main' block to another file, everything works well, i.e, there is only one VAR.
c.py:
import a
import b
if __name__ == '__main__':
a.VAR = -1
a.p()
b.p()
So my question is:
Why do the last two lines of a.py print different results?
Don't they print the same VAR variable in a.py?
BTW, I'm using python 2.7 on win7.
Thanks.
You might want to read up on global variables? To quote:
If a variable is assigned a new value anywhere within the function’s body, it’s assumed to be a local. If a variable is ever assigned a new value inside the function, the variable is implicitly local, and you need to explicitly declare it as ‘global’.
Edit: to elaborate, here's what happens (leaving out c.py for clarity):
File a.py is executed.
File b.py is imported, and in turn imports a.py again.
Via b's import, VAR is defined in with a value of 1. This ends b`s import.
The __main__ part in a.py is executed in its own scope; VAR is set to -1 there, and p() is ran: this displays -1, as VAR was just set to.
Then b.p() is executed, which in turn runs a.p(). Because VAR from the perspective of b.py (different scope) still has a value of 1, the print statement just outputs 1.
You'll also notice that the id's are different in both print statements: this is because the VAR's live in a different scope, and are not connected in any way. They are disconnected because __main__ lives in a different, anonymous scope: the scope in which the Python interpreter executes. This is briefly discussed in the docs.