Reputation: 329
I have a folder structure like this:
.
├── db
│ └── mysqldb1.py
└── helpers
├── __pycache__
└── context.py
helper/context.py
contains a Singleton class like:
class Context():
g = None
def __init__(self):
self.a = 'blah'
self.b = 'blabla'
self.conn = None
@classmethod
def init_g(cls):
if not cls.g:
cls.g = cls()
if __name__ == '__main__':
Context.init_g()
from db.mysqldb1 import get_conn
Context.g.conn = get_conn()
In db.mysqldb1.py
I have:
from helpers.context import Context
def get_conn():
a = Context.g.a
b = Context.g.b
... # more logic
When I execute python -m helpers.context
from root folder, I get:
Traceback (most recent call last):
File "/usr/local/Cellar/python/3.7.6_1/Frameworks/Python.framework/Versions/3.7/lib/python3.7/runpy.py", line 193, in _run_module_as_main
"__main__", mod_spec)
File "/usr/local/Cellar/python/3.7.6_1/Frameworks/Python.framework/Versions/3.7/lib/python3.7/runpy.py", line 85, in _run_code
exec(code, run_globals)
File "/Users/ttomson/Codes/test/helpers/context.py", line 17, in <module>
Context.g.conn = get_conn()
File "/Users/ttomson/Codes/test/db/mysqldb1.py", line 4, in get_conn
a = Context.g.a
AttributeError: 'NoneType' object has no attribute 'a'
The python interpreter complains that Context.g was never initialized. Why is that the case?
if __name__ == '__main__':
Context.init_g()
Did I not initialize it when I executed the above? Please help me understand this.
Upvotes: 2
Views: 81
Reputation: 282043
This is a weird interaction between __main__
and circular imports. The fix is to change your code to avoid circular imports.
When you run python -m helpers.context
, Python runs a version of helpers.context
as the __main__
module, separate from the regular helpers.context
module. This version runs the if __name__ == '__main__':
block, and initializes its own version of Context
.
db.mysqldb1
tries to import helpers.context
, and it gets the regular version of helpers.context
. This version never initialized its Context.g
, which is why you get the AttributeError.
Upvotes: 4