Skip to content
Advertisement

Method of class in module doesn’t see my globals()

I have a problem with globals using method of class from my testmodule

Example: Text of my test module:

cat ./testmodule.py

JavaScript

Text of my test class the same:

JavaScript

Text of my test func, nothing new:

JavaScript

And go to test it.

JavaScript

Everything is ready, let’s test

JavaScript

Variable exist

JavaScript

The same result, variable exist

JavaScript

Variable is lost.

How can i get the same result from testmodule like from testclass and testfunc?

Advertisement

Answer

Expanding on @chepner’s comment: globals() returns the module-level variables of the current module only.

  • When you define testfunc() in the REPL, it is defined as __main__.testfunc and invoking globals() returns essentially __main__.__dict__.
  • When defined in your testmodule, it is defined as testmodule.testfunc and globals() returns testmodule.__dict__.

If you want testfunction to access globals of another module, you need to ensure that globals() is called in the lexical scope of the module. The easiest was is to extend testfunction to expect a dictionary as argument:

JavaScript

Additional details

  • __main__ isn’t defined by default. You need to import __main__ before you can use it. But you can see that the current module is named __main__ from the variable __name__.
  • When you run python somescript.py, the contents of the file are executed as the __main__ module, not as a somescript module.
  • Python has closures, and functions inside modules behave essentially like closures over the module scope – so I would have expected globals() to be a member of every module. Then the following would have yielded the expected result:

    JavaScript

    but again, this returns the globals of only the testmodule. Instead globals is defined only in __builtin__, and seems to use the scope of the caller as hidden argument. As a consequence:

    JavaScript

    Normally expect f and lambda: f() to have the same result.

  • You can’t rely on somemodule.__dict__ to be defined. A module may actually choose to return some wrapper object instead of a normal module object, when you import it. Actually, nothing even enforces that somemodule has typical module semantics! E.g. try the module:

    JavaScript

    A real-world example for such changes would be os.path:

    JavaScript
User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement