I have thousands of models in my package, each of them contains one class. Users can choose model they want to use by:
from myproject.type1.models.m1 import m1
Very inconvenient.
The subfolder looks like:
type1/
├── __init__.py
├── constant.py
├── decorator.py
├── models
│ ├── m1.py
│ ├── m2.py
│ ├── m3.py
...
│ ├── m999.py
So I write a module loader to load module dynamic:
class ModelLoader:
def __init__(self, model_path):
self.model_path = model_path
self.models = {}
def __getattribute__(self, __name: str) -> Any:
try:
return super().__getattribute__(__name)
except AttributeError:
if __name not in self.models:
try:
model_file = import_module(self.model_path + "." + __name)
model = getattr(model_file, __name)
self.models[__name] = model
return model
except ModuleNotFoundError:
raise AttributeError(f"Model {__name} not found")
else:
return self.models[__name]
With this, user can load module by just:
models = ModelLoader(__name__.rsplit(".", 1)[0] + ".models")
m1 = models.m1
m2 = models.m2
But this cause a problem.
Vscode or pycharm can not provide IntelliSense for m1 if it is imported by ModelLoader
.
Intellisense works:
not work:
How can I let IDE know class ModelLoader
have a member m1
and is defined in myproject.type1.models.m1
?
I do not import all module in my package's __init__
since it will harm user experience, it takes about 30s to import all models.
You can try and generate a .pyi
file based on the type1
directory.
Pylance can use that to feed its static code analysis.