The problem is that when you do -
from a import Real, Fake
Basically, you import these two classes into the initialize script namespace and create the Real and Fake names in the initialize script namespace. Then you specify the name Real in the initialize script on Fake , but that will not change anything in the actual module a .
If initialize script is another .py / script module when run at the beginning of your source program, you can use below -
if env == 'dev': import a a.Real = a.Fake
Note: this would make a.Real reference to the Fake class whenever you use the Real module from a after executing the specified line.
Although I would suggest that it is best to do this in your module a , by providing the ability to check env in this module, as -
if <someothermodule>.env == 'dev': Real = Fake
As asked in the comments -
Doesn't import also import into script namespace initialization? What is the difference between importing modules and classes?
The fact is that when you import only a class using from a import class , what you actually do is create this class variable in the module namespace (in the module into which you import it), changing this variable to a point to something new in this module namespace does not affect the source class in its source module object, it only affects the module in which it was changed.
But when you do import a , you simply import module a (and when you import a module object, it is also cached in the sys.modules dictionary, so any other imports in a from any other modules will get this cached version from sys.modules ) (Another note : from a import something also internally imports a and caches it in sys.modules , but allows you to not go into these details, since I think that is not necessary here).
And then when you do a.Real = <something> , you change the Real attribute of the object of module a , which points to the class, to something else, it directly mutates module a , therefore, this change is also reflected when module a imported from another module.