I'm trying to import files and here is the situation.
file1.py contains:
from file2 import *
username = "steven"
action()
file2.py contains:
def action():
print username
But i can't print the username because the variable 'username' is declared in file1 but not file2 (for the function uses the variable)
This is not the actual code, but can I not use variables from file1 in functions from file2?
A better approach is to not rely on globals from another module, and simply pass the name into the file2.action() function:
import file2
username = "steven"
file2.action(username)
def action(name):
print name
What you intend, in the way you want,would require file1 import file2 and vice-versa - in a plain code, that would lead to a circular import, which plainly does not work.
But besides that, if your functions, classes or methods on a file need to know about data that is on the context of a file that imported them, the right thing to do is to pass this data in as function parameters.
In your case, your "action" function should be:
def action(username):
print username
and on file1:
from file2 import action
username = "steven"
action(username)
(You also should avoid using "import *" as it hides where names come from when reading the code, making it hard to maintain)
Of course, Python being Python, there are work-arounds to do exactly what you want - you could create a special decorator to use on your imported functions that would recreate your function from another file, pointing it to the global variables from the current module - but that would be just silly.
The "OOP" paradigm allows for one silly case which is more or less like what you are intending to do - where a method uses a class attribute - and if that attribute is overridden in a subclass, the method - even the original superclass method, will use the new attribute value - like in:
class A(object):
username = ""
def action(self):
print self.__class__.username
and class B could be defined in other file, as you intend to:
from file2 import A
class B(A):
username = "Mike"
b = B()
b.action()
And now, just for giving you a complete answer - here is some code that will do what you want - but _don't do it - modify yoru functions to take parameters instead.
What can be done is having a function to read the global variables of the place from where it was called. That is not only "not a good pratice" - it is just wrong, except for some very well documented frameworks where "magic variable names" are used for configuration. Even when I find a framework with this bad habit, I tend to patch its functions so that I can pass the configuration explicitly via a function call.
from inspect import currentframe
def action():
caller_frame = current_frame(1)
caller_globals = caller_frame.f_globals
print caller_globals["username"]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With