Let's take a project with this folder structure:
> eval
> a
> __init__.py
> a.py
> b
> __init__.py
> b.py
__init__.py
__init__.py
m.py
Content of __init__.py in a folder:
from eval.a.a import A
Content of a.py:
class A:
def __init__(self) -> None:
pass
def __repr__(self) -> str:
return "Class A"
def __str__(self) -> str:
return "Class A"
def exec(self):
a = eval('A()');
print(a)
b = eval('B()');
print(b)
Content of __init__.py in b folder:
from eval.b.b import B
Content of b.py:
class B:
def __init__(self) -> None:
pass
def __repr__(self) -> str:
return "Class B"
def __str__(self) -> str:
return "Class B "
def exec(self):
a = eval('A()');
print(a)
b = eval('B()');
print(b)
Content of __init__.py in eval folder:
from eval.a.a import A
from eval.b.b import B
__init__.py outside eval folder has nothing inside.
Content of m.py:
from eval.a import A
from eval.b import B
a = eval('A()');
print(a)
b = eval('B()');
print(b)
Until now it works, creating my A() and B() objects, printing:
Class A
Class B
But if I change m.py to:
from eval.a import A
from eval.b import B
a = eval('A()');
print(a)
b = eval('B()');
print(b)
print('Running A.exec() now:')
a.exec()
print('Running B.exec() now:')
b.exec()
Then I will get:
Class A
Class B
Running A.exec() now:
Class A
Traceback (most recent call last):
File "c:\dev\test\python\teste_eval\m.py", line 19, in <module>
a.exec()
File "c:\dev\test\python\teste_eval\eval\a\a.py", line 15, in exec
b = eval('B()');
File "<string>", line 1, in <module>
NameError: name 'B' is not defined
Then the questions are:
Why my class B are not available to my A.exec() if in the file that I created the class I had imported both classes A and B?
How to fix it? What means make any class in my system available to be created by any class even inside a separate module (like 'eval' module in this example)?
There are a best way to create these class dynamically than use eval function?
Thanks for your support.
I just found a manner to get all modules loaded.
This is a possible solution:
This code will return:
For the system structure used in the example.
I think that the final solution should be based on this list of modules loaded.
Thanks to everyone who tried to help.
Updated:
Another possibility is to go through the file system from the starting point to the last folder, as shown here:
And then, I can just use:
To get all that I need to import and execute this doing:
So, I will have dynamically imported all the classes defined within the application.