Reputation: 626
It seems depending on where they're accessed from, class attributes don't have the same value. I don't understand why that's the case, and any help in understanding this or working around it would be welcome.
Consider the following .py files :
foo.py:
from bar import *
class Foo:
someAttribute = None
@classmethod
def update(cls, value):
cls.someAttribute = value
def main():
Foo.update("some value")
print(Foo.someAttribute)
bar = Bar()
bar.showStuff()
if __name__ == '__main__':
main()
and bar.py:
from foo import *
class Bar:
def showStuff(self):
print(Foo.someAttribute)
One would expect and intend the output to be "some value" for both print
instructions. Yet my output is the following :
$ python foo.py
some value
None
Upvotes: 3
Views: 84
Reputation: 1125138
You have two copies of the foo
module in memory. One is called __main__
, the other is called foo
. That's because you run foo
as a script, which is then stored as the __main__
module.
So when you run python foo.py
the following happens:
sys.modules['__main__']
is created to hold your script namespace.from bar import *
is run
sys.modules['bar']
is created to hold the bar
module namespace.from foo import *
is run
sys.modules['foo']
is created to hold the foo
module namespace.from bar import *
is run, the sys.modules['bar']
object is found.sys.modules['bar']
module, nothing is importedFoo
class and the main
function are added to the foo
module.if __name__ == '__main__'
is skipped, this is the foo
module.Foo
and main
are added to the bar
namespaceBar
class is added to the bar
namespaceFoo
, main
and Bar
are added to the __main__
namespaceFoo
and main
are created in the __main__
namespace.if __name__ == '__main__'
block is executed and main()
is called.Either import from __main__
in bar
, or use a third python file to be the main script.
Note that if you use from __main__ import *
, then you do have a circular import problem. That's because the from __main__ import *
won't include anything that has not yet been executed when the from foo import *
line runs, see the above break-down.
Upvotes: 7