Reputation: 228
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?
Upvotes: 3
Views: 11356
Reputation: 110666
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"]
Upvotes: 2
Reputation: 43111
No, file2 cannot access the global variables in file1 without explicitly importing them. This is actually a good thing, since otherwise, a project which imports a bunch of modules would easily be overwriting eachothers data accidentally.
Why not make the username an argument of the method?
file1.py:
from file2 import action
username = "steven"
action(username)
file2.py:
def action(username):
print username
Upvotes: 1
Reputation: 994531
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
Upvotes: 5
Reputation: 298512
It's best if you use classes, as they scale quite easily:
file1.py:
from file2 import ExtendedClass
class MyClass(object, ExtendedClass):
def __init__(self):
Object.__init__(self)
self.username = 'steven'
file2.py:
class ExtendedClass:
def action(self):
print self.username
Even though somewhat hacky-methods exist and solve your problem, you'll appreciate classes once you use them.
Upvotes: 0
Reputation: 49105
But file2.py
didn't import file1.py
; how's it supposed to know that username
even exists?
Incidentally, I try to avoid circular dependencies in my code (i.e. module x import module y, and module y imports module x), so simply importing file1
into file2
may not be the best solution.
Upvotes: 1