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, thePiyo` 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, theBase 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, thePiyo` 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