3

Assume I have this barebones structure:

project/
 main.py
 providers/
 __init.py__
 acme1.py
 acme2.py
 acme3.py
 acme4.py
 acme5.py
 acme6.py

Assume that main.py contains (partial):

if complexcondition():
 print providers.acme5.get()

Where __init__.py is empty and acme*.py contain (partial):

def get():
 value=complexcalculation()
 return value

How do I change these files to work?

Note: If the answer is "import acme1", "import acme2", and so on in __init__.py, is there a way to accomplish that without listing them all by hand?

asked Apr 20, 2009 at 22:10
2

3 Answers 3

6

hey! two years later but... maybe could be helpfull to some one

make your providers/__init__.py like that:

import os
import glob
module_path = os.path.dirname(__file__)
files = glob.glob(os.path.join(module_path, 'acme*.py'))
__all__ = [os.path.basename(f)[:-3] for f in files]

you don't have to change it later if add or remove any providers/acme*.py

then use from providers import * in main.py

answered Feb 9, 2011 at 10:25
Sign up to request clarification or add additional context in comments.

3 Comments

This introduces 'magic'; i.e. unexpected sideeffects. The mere existance of a file should not cause code execution. This goes against the principle of least surprise, making this a bad idea (tm). -1
@koert what is wrong with a little of magic? :P In this case the question say: "is there a way to accomplish that without listing them all by hand?"... he is asking for a little of magic, I think. Maybe the files are automaticaly generated and he don't want to edit his code each time a new one appear. How you could accomplish this without magic?
You are right, there is no way to accomplish your scenarios without magic. On the other hand, this type of magic is the start of a sysadmin hell (been there, done that).
5

If I'm reading your question correctly, it looks like you're not trying to do any dynamic importing (like in the question that Van Gale mentioned) but are actually trying to just import all of the modules in the providers package. If that's the case, in __init__.py you would want to have this statement:

__all__ = ["acme1", "acme2", "acme3", "acme4", "acme5", "acme6"]

Then to import everything you would use from ... import *

from providers import *

And then instead of using the package name explicitly in the code, you would just call the imported classes

acme1.get()
acme2.get()

If you have enough modules in the providers package that it becomes a problem populating the __all__ list, you may want to look into breaking them up into smaller packages or storing the data some other way. I personally wouldn't want to have to deal with dynamic importing schennagins every time I wanted to re-use the package.

answered Apr 21, 2009 at 2:06

Comments

3

This question asked today, Dynamic Loading of Python Modules, should have your answer.

answered Apr 20, 2009 at 22:28

1 Comment

Not quite what I was hoping for, but it led me to a workable solution, thanks.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.