简体   繁体   中英

change global variable in different files

I do not really understand how python handles global variables if the code is split into different files.

Assuming I have 3 files: class1.py, class2.py, main.py

In main.py I define a global variable

from class1 import Class1
from class2 import Class2
global sys
sys = constructor()

This object contains information about the system which I simulate and is used and manipulated by the classes defined in class1.py and in class2.py.

One could of course argue that this is bad style and one should avoid exploiting global variables like this, but this is not the point here.

If now I use sys in either class, it is unknown. To use a global variable one could of course define them somewhere and then include this file. But then, the changes that are made by the classes would not effect each other, so I don't want to do this.

Another way would be to define a new Class SuperClass where sys is a member. If now Class1 and Class2 are inherited from SuperClass, I could probably do some stuff with the super keyword. I do not really want to do this...

Long story short... Is there a way to define an python object such, that it behaves similar to a C-style global variable?

Maybe it helps if I give an example:

  • sys includes the system frequency
  • a function of Class1 changes the system frequency
  • a function of Class2 simulates stuff and uses the system frequency
  • based on this the system power is changed in sys
  • a function of Class1 performs a task with updated system power

No, there's no way to have "C-style global variables", and that's by design. Explicitely pass your sys objects to Class1 and Class2 when instanciating them and you'll be done, with a clean, readable, testable, maintainable implementation:

# lib.py
class Class1(object):
    def __init__(self, sys, whatever):
        self.sys = sys
        # ...

class Class2(object):    
    def __init__(self, sys, whateverelse):
        self.sys = sys
        # ...


# main.py

from lib import Class1, Class2

def main():
    sys = constructor()
    c1 = Class1(sys, 42)
    c2 = Class(sys, "spam")

    # now you can work with c1 and c2

if __name__ == "__main__":
    main()

To answer your very first question:

I do not really understand how python handles global variables if the code is split into different files.

Python's "globals" are module-level names. At runtime, modules are objects (instances of the module type), and all names defined at the module's top level become attributes of the module instance - "defined" being either by assignment, by a def or class statement or by an import statement.

From within the module, top-level names are accessible by their unqualified names in all the module's code - you only need the global keyword if you want to rebind a top-level name from within a function.

From outside the module, you can access those names using the qualified path, ie if module1 defines name foo , you can access it from module2 by importing module1 (making module1 a top-level name in module2 ) and using the usual attribute resolution (dotted.name) syntax.

You can also import foo directly using from module1 import foo , in which case a new name foo will be created in module2 and bound to module1.foo (more exactly: bound to the object which is at this point bound to module1.foo ). The point here is that you know have two distinct names in two distinct namespaces, so rebinding either will only affect the namespace in which it's rebound.

You certainly want to read Ned Batcheler's famous article on Python's names , it's usually a good starting point to understand all 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