0

It is possible to modify an instance variable from another file?

What I want is to modify an instance variable inside File_1 from File_2.

For example:

//File 1
import File_2

class Main:
    def __init__(self):
        self.example = "Unmodified"

    def modify(self):
        File_2.modify()

main = Main()
main.modify()


//File 2
import File_1

def modify():
    File_1.main.example = "Modified"

This gives me the following output:

Traceback (most recent call last):
File "File_1.py", line 4, in <module>
  import File_2
File "File_2.py", line 3, in <module>
  import File_1
File "File_1.py", line 14, in <module>
  main.modify()
File "File_1.py", line 11, in modify
  File_2.modify()
AttributeError: 'module' object has no attribute 'modify'

Why?

EDIT (to explain better):
The instance of the main class (in file 1) has a variable; what I want is to modify that variable from another file (file 2). I modified a little bit the code:

//File 1
import File_2

class Main:
    def __init__(self):
        self.example = "Unmodified"

    def modify(self):
        File_2.modify()

if __name__ == "__main__":
    main = Main()
    main.modify()


//File 2
def modify():
    //do some stuff
    //now I want to modify the example variable from the main class, but how?
Qadric
  • 13
  • 1
  • 5

2 Answers2

1

Your code is full of cyclic imports, take a look at Python: Circular (or cyclic) imports to know what I'm talking about.

Basically the problem is that when the compiler comes to this line:

File_2.modify()

File_2 is not completely loaded, menaning that the compiler have not yet read the lines:

def modify():
    File_1.main.example = "Modified"

Since it was brought back to File_1 from the previous:

import File_1

Besides this, you're code seems quite strange. If you care to provide more information about your real code, maybe a better design could solve your problem.

Edit: You have to remove the cyclic imports. One way to do what you seem to need is to pass an argument to the File_2.modify(arg) function, and work on that:

# File_2
# !! do NOT import File_1 in this file
def modify(obj):
    obj.value += 7

But in your case you'll have to pass the whole object (self) to the modify function, and is some of a waste to modify only one value.

It would be better to do something like:

# File_1
import File_2
class Main:
    # ...
    def modify()
        self.value = File_2.modify(self.value)

# File_2
# !! do NOT import File_1 in this file
def modify(num):
    return num + 7

But once again this are just examples, since your not showing your real code, we can't really tell you what's best in your case (maybe neither of the above) or help you very much.

Community
  • 1
  • 1
Rik Poggi
  • 28,332
  • 6
  • 65
  • 82
  • Thanks for the answer, I edited the question to explain better. – Qadric Mar 02 '12 at 03:45
  • wwe can understad what you want - and we both answered what your problem is - cut off the cyclic imports, and your code will work just as you wish it too. – jsbueno Mar 02 '12 at 05:27
  • @Adrian: *jsbueno* is right, you *have* to remove your cyclic imports. I've edited my answer throwing there some examples (without your actual code is a little hard to help you). – Rik Poggi Mar 02 '12 at 11:04
  • OK, this works, but not in my case. I am making an application with an appIndicator (on Ubuntu). The main instance is creating the appIndicator; in the other module I do other stuff and depending on that I need to update in "real time" (a thread) the appIndicator created in the main module. Is it possible to do that? – Qadric Mar 02 '12 at 14:18
  • @Adrian: If that is your question, you should have asked that. You'll need to provide a method in the main module to call from wherever you want to modify your appIndicator. Take a careful look at this [other question](http://stackoverflow.com/q/9190169/1132524) :) – Rik Poggi Mar 02 '12 at 19:57
  • Is it really necessary to use Queue? – Qadric Mar 04 '12 at 22:46
  • I found [this question](http://stackoverflow.com/questions/142545/python-how-to-make-a-cross-module-variable); this would be more simple, but are there downsides to that? – Qadric Mar 05 '12 at 00:10
  • @Adrian: You already got two answers and some links/advices. If they're not clear to you, open a new question and state clearly your problem/what you don't understand there. It's not possible to explain everything here by comments. – Rik Poggi Mar 05 '12 at 00:46
0

What does not work in Python is this "cross importing" you are trying to do - When you do both files import each other, you have inconsistencies and undesireable side effects. In this case when the main.modify() line is run at File_1 parsing, it does find a not yet fully initialized "File_2" module in memory - where the "modify" function does not exist yet.

Reorder yoru code so you don't have the cyclic imports, and it should work - For example, if teh file you import first - or run as main module, is File_1, inside File_2, instead of import File_2 in the first line, import it just inside the modify function, like this:

#File 2


def modify():
    import File_1
    File_1.main.example = "Modified"

N.B. these imports, since they are referencing a module that isa ctually already imported on the interpreter, just bind the module object, already loaded, to the variable in the running scope - in other words, Python won't do a disk access for the module file at each time the function is called.

jsbueno
  • 99,910
  • 10
  • 151
  • 209