0

How does Python resolve global variables in calls between packages, especially in cases there are global variables with the same name present?

For example. Let there ba a package P1 containing BaseClass. Let there be two packages P2 and P3, containing classes Derived1 and Derived2 that inherit BaseClass correspondingly. Also, let P2 and P3 both contain variable named gvar (for example, defined in their init.py files).

Both of derived classes in their constructors have a call to baseClass constructor through super.

If in BaseClass constructor there is a reference to gvar, what would happen? Is there a way to ensure that during instantiation of Derived1 gvar from P2 would be used?

Why am i bothering with global variables: in my real life case there are tens of classes in P1 and P2, and i would like to avoid changing them all (to add package-specific gvar to their definitions, or adding another common ancestor with it).

Srv19
  • 3,458
  • 6
  • 44
  • 75

2 Answers2

1

Globals are per module. Globals in P1, P2 and P3 are all independent.

Python functions also store a pointer to the globals mapping of their module, so even when imported, globals are still looked up in the module they were defined in.

For your example ,that means that a global referenced from P2.Derived1.__init__ is looked up in P2, and a global referenced from P3.Derived2.__init__ is looked up in P3. Both packages would need to import P1.BaseClass, and any globals P1.BaseClass.__init__ might look up are sourced from P1.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • Well, i presumed that it was possible that the global context of calling function is passed down to its callees, and so `P1.BaseClass.__init__` would have access to globals available for the `P2.Derived1.__init__` that called it. – Srv19 Jan 09 '17 at 08:08
  • 1
    @Srv19: nope, that's not how Python works. That would be incredibly impractical, because that would require you to import all globals any code you wanted to use needed. For example, the `argparse` module imports `os`, `re`, `sys`, `textwrap` and `copy`. If globals needed to be taken from the caller namespace, you'd have to import those modules too just to be able to run `argparse` in your code. – Martijn Pieters Jan 09 '17 at 08:17
  • i do not understand. Why is there a need to import anything else? I mean, global variables should be accessible (or not, depending on execution context) by name without importing them - it is dynamic language after all, not C where evarything should be known at compile time – Srv19 Jan 09 '17 at 09:16
  • @Srv19: What I meant is that you have to pick one model over another. Either you have dynamic scoping (and the names are looked up in the caller namespace), or you have static scoping (what Python uses, and the module in which a function is defined determines where globals are found). Your presumption was that Python would use dynamic scoping, and if that was the case, then you'd have to use additional imports. I was illustrating how impractical that'd be. – Martijn Pieters Jan 09 '17 at 09:30
  • Thanks for clearing this up for me – Srv19 Jan 09 '17 at 13:25
0

"Global" variables are only global to the module (i.e., the file) in which they are defined. If you have a function (including a method) in a given file, and that function refers to a global variable gvar, it will always refer to a global variable gvar within that module, not in any other module.

You can, however, modify or create global variables from outside the module. For instance, if you do import blah and then blah.gvar = 2, you have effectively created a global variable gvar inside blah (or changed its value, if it already existed), and code inside blah that refers to gvar will use the value you have set.

BrenBarn
  • 242,874
  • 37
  • 412
  • 384