简体   繁体   中英

Python cross module variables and imports

I see that there are other questions related to cross module variables, but they don't really fully answer my question.

I have an application that I have split into 3 modules + 1 main application, mainly for ease of readability and maintainability.

2 of these modules have threads with variables that need to be modified from other modules and other module threads.

Whilst I can modify a module's variable from the main code, I don't appear to be able to modify one module's variable from another module unless I import every module into every other module.

The example below where a&b are imported into main and a module a needs to access a variable in module b:

main
 module a
   var a
 module b
   var a

main
 a.a = 1
 b.a = 2

module a
 b.a = 3

module b
 a.a = 0

without importing module a into module b and importing module b into module a, can this be achieved globally through the main program ?

If I do have to import a and b into main, and then import a into b and b into a, what are the implications in terms of memory and resource usage / speed etc ?

I tried the suggestion from @abarnert:

#moda
vara = 10

#modb
print(str(vara))

#main
import moda
from moda import vara
import modb

however I get "name error vara is not defined"

If you want to be able to modify a module-level variable from a different module then yes, you will need to import the other module. I would question why you need to do this. Perhaps you should be breaking your code into classes instead of separate modules.

For example you could choose to encapsulate the variables that need to be modified by both modules inside a separate class and pass a single instance of that class to all classes (or modules but you should really use classes) that need it.

See Circular (or cyclic) imports in Python for more information about cyclical imports.

If the code in the modules are defined as classes, and the main program creates instances of these classes, the main program can pass an instance of one module class to another, and changes to that instance will be reflected everywhere. There would be no need to import a or b into each other, because they would simply have references to each other.

If I do have to import a and b into main, and then import a into b and b into a, what are the implications in terms of memory and resource usage / speed etc ?

Absolutely none for memory—every module that imports a will get a reference to the exact same a module object. All you're doing is increasing its refcount, not creating new objects.

For speed, the time to discover that you're trying to import a module that already exists is almost nothing (it's just looking up the module name in a dictionary). It is slightly slower to access aa than to just access a . But this is very rarely an issue. If it is, you're almost certainly going to want to copy that value into the locals of whatever function is accessing it over and over, at which point it won't matter which globals it came from.

without importing module a into module b and importing module b into module a, can this be achieved globally through the main program ?

Sure. All you have to do is import (with from a import a or import aa as aa or whatever) or copy the variables from module a into main .

Note that just makes a new name for each value; it doesn't make references to the variables. There is no such thing as a reference to a variable in Python.

This works if the variables are holding constants, or if they're holding mutable values that you modify. It just doesn't do anything useful if the variables are names that you want to rebind to new values. (If you do need to do that, just wrap the values in something mutable—eg, turn each variable into a 1-item list, so you can rebind a[0] instead of a , which means anyone else who has a reference to a can see your new a[0] value.)

If you insist on a "true global", even that isn't impossible. See builtins for details. But you almost certainly don't want this.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM