Why do global functions not work as I expect when importing?

In the foo.py file, I have the following:

 d = {} d['x'] = 0 x = 0 def foo(): global d global x d['x'] = 1 x = 1 

Then in the interpreter:

 >>> from foo import * >>> d['x'] 0 >>> x 0 >>> foo() >>> d['x'] 1 >>> x 0 

I was expecting this:

 >>> x 1 

What? I do not understand?

+6
source share
2 answers

The global namespace foo imported into your current namespace only once (when you execute from foo import * ). After that, if you change the foo namespace, it will not be reflected in your current namespace.

Note that you can still change objects in the foo namespace and see the changes in the current namespace. That is why you see changes in d . You still have a reference to the same d object that is in the foo namespace.

But when you install:

 x = 1 

This rechecks the new object in the foo namespace.

+3
source

Your foo module and the main module that imports it (named __main__ ) have separate namespaces.

Here's what happens:

  • Importing foo sets foo global variable x to access integer 0 .
  • This link is copied to __main__ as a global variable x .
  • You call foo.foo() , which sets the global variable foo x to access integer 1 .
  • You print the global variable __main__ x . Since you never changed what relates to this x value, it still refers to 0 , this is what is printed.

In short, importing a name into a module does not create any binding between the names in the two modules. Initially, they refer to the same value, but if one name is bound to another object, the other does not necessarily follow.

This is (one) the reason why import foo is generally a better idea. Referring to foo.x explicitly in __main__ , foo matches the global variable x exactly and will refer to the current value of the name, even if it has been changed.

+2
source

Source: https://habr.com/ru/post/958808/


All Articles