There is a circular import problem. For example
hoge.py
# coding: utf-8
import piyo
class Base:
pass
class Hoge(Base):
pass
When,
piyo.py
# coding: utf-8
import hoge
class Piyo(hoge.Base):
pass
If there are two Python scripts, " python3 hoge.py
"will not cause an error, but if you execute" python3 piyo.py
",
Traceback (most recent call last):
File "piyo.py", line 3, in <module>
import hoge
File "hoge.py", line 3, in <module>
import piyo
File "piyo.py", line 5, in <module>
class Piyo(hoge.Base):
AttributeError: partially initialized module 'hoge' has no attribute 'Base' (most likely due to a circular import)
AttributeError will occur like this.
(Looking now, he politely says "most likely due to a circular import")
One solution, on the other hand, is to make the Base
class a separate script and import that script from both hoge.py
/ piyo.py
.
By the way, when such a problem occurs occasionally, it comes up on the Q & A site, but the answer can be the same as above, but in fact the cause of the exception is quite deep, and always "Hmm. I was worried, and when I understood the reason, I thought, "Oh, this is the one I was worried about before. See you again." Today, I'll make a note of that.
Now, here are some Python specs you need to know to understand the cause of this problem.
sys.modules
with the module name as the key, and if imported from the second time onwards, just return the object saved in sys.modules
and the module script Processing is never executed.Now, with this in mind, let's verify what happens when we run the previous " python3 piyo.py
".
piyo.py
"," ʻimport hoge "and
hoge.pyare imported. At this point, the
Piyo` class has not yet been defined. hoge.py
"," ʻimport piyo" is executed, but since "
piyo.py` "is already loaded, it does nothing.Base
class and Hoge
class written after " hoge.py
"are defined.As you can see, it runs without any problems ... that? Something is different.
Now let's run " python3 hoge.py
".
hoge.py
"," ʻimport piyo "and
piyo.pyare imported. At this point, the
Base and
Hoge` classes are undefined. piyo.py
"," ʻimport hoge" is executed, but since "
hoge.py` "is already loaded, it does nothing.hoge.Base
class is referenced as the derived class of the Piyo
class, but the Base
class definition is not executed in hoge.py
, so the hoge
module There is no Base
in the attribute and I get a ʻAttributeError` exception.In this way, an error occurs ... that?
In this way, if you find the cause, it will be the opposite of the actual operation. I always have a problem here, but I remember another Python specification and solve it.
__main__
".Based on this, let's verify the operation of " python3 piyo.py
"again.
piyo.py
"," ʻimport hoge "and
hoge.pyare imported. At this point, the
Piyo` class has not yet been defined. hoge.py
"," ʻimport piyo" is executed. "
Piyo.py"is already loaded, but it is ** the module name is"
main" **, and the module "
piyo"is not loaded, so"
piyo again .py
"is executed. At this point, the Base
and Hoge
classes that follow are not running, so they are not yet defined. piyo.py
"," ʻimport hoge" is executed, but since "
hoge.py` "is already loaded, it does nothing.hoge.Base
class is referenced as the derived class of the Piyo
class, but since the Base
class definition is not executed in hoge.py
, the hoge
module There is no Base
in the attribute and I get a ʻAttributeError` exception.Sure, you get a ʻAttributeError` exception. As a test,
piyo.py
# coding: utf-8
import hoge
import sys
print('\n'.join([repr(n) for n in sys.modules.items()]))
class Piyo(hoge.Base):
pass
Let's take a look at the contents of sys.modules
.
('__main__', <module '__main__' from 'a/piyo.py'>)
('piyo', <module 'piyo' from '/path/to/a/piyo.py'>)
(Omitted except necessary)
As mentioned above, you can see that " piyo.py
"is loaded twice.
Now, let's review.
Basically, once a script is imported, it will not be executed twice, but a script that is executed at startup may be executed twice. So the script that is executed at startup is
if __name__ == '__main__':
main()
So, you should look at your module name and run it only the first time.
Recommended Posts