Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling variables from other files in Python

Tags:

python

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?

like image 814
Steven Ritchie Avatar asked Aug 07 '26 09:08

Steven Ritchie


2 Answers

A better approach is to not rely on globals from another module, and simply pass the name into the file2.action() function:

file1.py

import file2

username = "steven"

file2.action(username)

file2.py

def action(name):
    print name 
like image 142
Greg Hewgill Avatar answered Aug 09 '26 22:08

Greg Hewgill


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"]
like image 34
jsbueno Avatar answered Aug 09 '26 23:08

jsbueno