11

How can I autoload all my modules that kept in different directories and sub directories?

I have seen this answer which is using __import__, but it is still not the autoload that I have in mind.

I'm thinking something similar to PHP autoloader. Even better something like Composer autoloader.

It seems that autoloader is not a popular thing in Python from the research I have gathered so far (can't be sure as I'm new in Python). Is autoloading something not encourage-able in Python?

My autoload code so far,

import os
import sys

root = os.path.dirname(__file__)
sys.path.append(root + "/modules")
sys.path.append(root + "/modules/User")
sys.path.append(root + "/modules/Article")

# IMPORTS MODULES
module = __import__("HelloWorld")
my_class = getattr(module, "HelloWorld")

# This is our application object. It could have any name,
# except when using mod_wsgi where it must be "application"
def application(environ, start_response):

    results = []

    helloWorld = my_class()
    results.append(helloWorld.sayHello())

    output = "<br/>".join(results)

    print output

    ...

As you can see that I still need to have these lines in order to load the modules,

sys.path.append(root + "/modules")
sys.path.append(root + "/modules/User")
sys.path.append(root + "/modules/Article")

What if I have tons of folders and sub folders? Am I going to list them all? It is going to a long list eventually, isn't?

Also, using __import__ seems does not make much of difference from this,

import os
import sys

root = os.path.dirname(__file__)
sys.path.append(root + "/modules")
sys.path.append(root + "/modules/User")
sys.path.append(root + "/modules/Article")

# IMPORTS MODULES
import hello
import HelloWorld

from HelloWorld import HelloWorld

# This is our application object. It could have any name,
# except when using mod_wsgi where it must be "application"
def application(environ, start_response):

The latter looks nicer and neater to me.

Any ideas?

Community
  • 1
  • 1
Run
  • 54,938
  • 169
  • 450
  • 748
  • sorry, deleted my comment. was not sure it might help. basically add `__init__.py` files to the folders. http://stackoverflow.com/questions/13215386/creating-python-packages – hiro protagonist Aug 18 '15 at 09:51
  • that's ok. Maybe I should look for how to turn these modules into package? I have `__init__.py` in each folder already. – Run Aug 18 '15 at 09:52
  • then you already have a package and can import as `from modules.User import HelloWorld` (or sth like that). only the path where `modules` can be found needs to be in the `PYTHONPATH`. – hiro protagonist Aug 18 '15 at 09:54
  • that's what i'm doing in the second code above but it is not as good as PHP's I must say.... unless Python has a different way of doing it? – Run Aug 18 '15 at 09:56
  • 1
    you could try to import the modules when they are needed only (i.e. inside a function...). may not be the best way to go... – hiro protagonist Aug 18 '15 at 10:35
  • OK. Thanks. I guess that id probably the way how Python does it. – Run Aug 18 '15 at 11:08
  • 1
    The Python way is to have explicit imports at the beginning of the module / script, cf https://www.python.org/dev/peps/pep-0008/#imports – bruno desthuilliers Aug 18 '15 at 11:42

2 Answers2

9

TL;DR : Forget about it and use explicit imports.

Longer answer:

Python is not PHP - neither from the technical POV nor from the design / philosophical one.

Parts of Python's philosophy (aka "Python's Zen") are "explicit is better than implicit", "Readability counts", and "In the face of ambiguity, refuse the temptation to guess" - which makes a "feature" like PHP's "autoload" highly unpythonic, as 1. it's way less explicit than a "import mymodule" or "from mymodule import SomeName", 2. it's also way less readable (you don't know clearly where a name is imported from), and 3. when two or more modules define a same name (which is perfectly valid and quite common in Python), it would have to try and guess which one you want (which would be technically impossible).

From a technical POV, there's no way you could implement such a feature in Python in a reliable way - cf point 3. above. While PHP's require statement and Python's import statement may look similar, they really work in a totally different way, and the "execution models" are also totally different.

bruno desthuilliers
  • 75,974
  • 6
  • 88
  • 118
  • What are 'POV' and 'cf'? – Run Aug 18 '15 at 14:28
  • I understand that this is not pythonic but yet is a common repetitive task for the programmers and as programmers we want to avoid this kind of stuff and focus on what really matters. We working with frameworks there are a lot of common patterns like import models on controllers and this such of thing. Rails solves this magically well, and saying just don't do this is a bad answer IMHO. What I usually do is importing the module with a short alias like `from . import models as m`. This solves 99% of the cases. Having good importer would be wonderful. – geckos Mar 19 '19 at 20:49
  • While some people may rage, there are possible solutions that are tool centric. Eclipse deals extremely good with java imports. These seems to be nicer that implicit imports – geckos Mar 19 '19 at 20:53
  • 1
    @geckos code is read much more often than it's written, so "magic" solutions à la rails tend to make you waste more time in the long run (figuring out where some class or function is defined) than properly setting up your environment (so you don't have to mess with `sys.path`) and writing a couple explicit imports. My experience is that being able to debug quickly is MUCH more important than saving a couple seconds and keystrokes every once in a while... – bruno desthuilliers Mar 20 '19 at 09:07
  • I never had problems finding where something is defined on rails, once you get the conventions everything just works. I have problems on something not being found because I typo a class name. I agree with you that debug time is much more important than saving typing, but still is something good. And there is no magic, everything works following strict and predictable rules. – geckos Mar 20 '19 at 14:47
  • I strongly disagree with all these people who say autoload will make you waste time in the future when you read the code and try to figure out where it comes from. Nowadays, almost every IDE includes the 'go to definition' feature. You don't need to worry about it, and put all your effort programming what really matters – Lerzenit May 12 '20 at 18:05
1

Automatic source code reloading in the way that PHP does it isn't practical in Python. I would suggest you go have a read of:

If you really really must have something, see the details of the automatic code reloader you can use with mod_wsgi described in that. Never use it on a production system though.

If you are doing development, you frankly may be better off using mod_wsgi-express. See:

One of the things mod_wsgi-express has is the --reload-on-changes option, which implements the automatic code reloading for you.

Graham Dumpleton
  • 57,726
  • 6
  • 119
  • 134
  • PHP's autoloader has nothing to do with reloading source code. It is about automatically including other PHP files. – pcworld Nov 02 '18 at 13:53