简体   繁体   中英

Python import all from folder

I have encountered issue while working on my Django project. I have multiple classes inside views.py. It had 1200 lines so I decided to move these views to seperated files inside new folder. Now one files, for example Customer.py has 2 classes for different operations.

This is my project structure before splitting views.py:

MyProject
  core
    -  urls.py
  api
    -  views.py
  manage.py

Project structure after splitting views.py

MyProject
  core
    -  urls.py
  api
    -  view
        -   *all the files with multiple classes in each file*
  manage.py

After splitting views.py I needed to import all classes from all files inside of the view folder inside core/urls.py. I have been trying to find out few hours now and can figure it out...

My current solution is that in urls.py im doing

from api.view import * 

while having init .py inside view folder which is doing

from .oneOfManyFiles import *

for all classes...

I highly dont like this solution, I would love to find out some good looking simple elegant solution. Is here anyone who can help me ?

Big thanks

Avoiding explicit imports

You can't avoid that, at least not without breaking code completion on IDEs.

import importlib
import os

filedir = os.path.dirname(__file__)
modules = [f[:-3] for f in os.listdir(filedir) if os.path.isfile(os.path.join(filedir, f)) and f.endswith('.py') and f != '__init__.py']
for module_name in modules:
    module = importlib.import_module(f".{module_name}", package=__name__)
    names = [x for x in module.__dict__ if not x.startswith("_")]
    globals().update({name: getattr(module, name) for name in names})

I wouldn't consider that good looking, simple or elegant.

Self-replacing generated imports

If what's bothering you is having to do it by hand, then probably the best thing you could do is write a script to generate the import statements and replace itself when run.

import os

filedir = os.path.dirname(__file__)
modules = [f[:-3] for f in os.listdir(filedir) if os.path.isfile(os.path.join(filedir, f)) and f.endswith('.py') and f != '__init__.py']
imports = [f"    from .{module} import *\n" for module in sorted(modules)]

with open(__file__, 'r') as f:
    this_script = list(f)[:17]

with open(__file__, 'w') as f:
    f.write(f"""{''.join(this_script)[:-1]}
try:
{''.join(imports)[:-1] if imports else '    pass'}
except ImportError:
    pass
""")

try:
    from .oneOfManyFiles import *
except ImportError:
    pass

For code completion, either run the project or python -m api.view.__init__ .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM