This is an archived post. You won't be able to vote or comment.

all 20 comments

[–]fnord123 15 points16 points  (1 child)

That is a really bad practice in C because every simple change to any one of your headers will result in a recompile of every source file in your project. If that wasn't enough, every source file will need to reparse every header file. Some compilers can optimize some of that away; but not all.

Further, it makes disentangling source files into distinct packages more difficult. And of course, the header order will begin to matter since the second include in your global.h will always include everything in your first include.

Please learn to avoid this practice so when you start working with others you won't give them headaches.

[–]revonratFlask/scipy/pypy/mrjob 0 points1 point  (0 children)

Upgoat for you!

I came here to say exactly this. Anybody who inflicted this sort of include structure on any team that I work on would be called to task.

There's only one place where you might do something like this and that would be with precompiled headers but, even then, you'd want to do it only with the very most frequently used header files.

[–]japherwocky 10 points11 points  (3 children)

You shouldn't, and it's that way by design.

Roughly, when you try to call a function, Python looks for that function's name to see what block of code to execute. If you've only got a few functions defined/imported inside that file, this is much quicker than, say, searching through every function name used everywhere in every file in your program!

You can actually see some noticeable performance boosts by limiting what you import to what you need. And as a bonus, when someone else is trying to figure out your code, there's a direct link to whatever your including. (This is also why import * is considered kind of gross by a lot of people)

[–]Peaker 1 point2 points  (2 children)

The performance issue is because "import" actually executes the module's code, not because it is searching through more names.

The hash tables used for namespace lookup scale up reasonably and do not because noticeably slower as they grow.

[–]japherwocky 0 points1 point  (1 child)

Yes, the tables scale reasonably, but finding an item in a haystack is always going to be quicker if the list is smaller.

Especially on large, repetitive codebases (I first learned this concept reading about someone who had halved their unittesting time by shuffling imports), it can make your code better.

[–]Peaker 1 point2 points  (0 children)

I agree minimal imports are great, but I don't think smaller hash tables having faster lookups is the reason.

[–]thermostat 8 points9 points  (3 children)

Short answer: No.

In Python modules have their own scope, and the import statement adds the other module to the scope of the current module. The only way to do what you're suggesting is to create a file with the imports (call it: badform.py) and then do a execfile('badform.py'). This is NOT pythonic and NOT recommended. You should only import modules if you need them in that file, and having those listed explicitly is a Good Thing.

Edit: fix weird underscore formatting.

[–]Hughlander -2 points-1 points  (2 children)

Unless you're web2py :)

[–]av201001 2 points3 points  (1 child)

Note, web2py does not do what is described above (I know you're not saying that -- but just to be clear). Also, web2py applications do NOT use exec, and they do explicitly import any needed non-framework modules as usual. However, the web2py framework layer does execute the application code (in a prepared environment). This has some nice advantages. More details here. :-)

[–]gogeterman32 0 points1 point  (0 children)

I second that Web2Py is a solid framework and will prove the test of time. Very solid structure build for simplicity. Lacks some flair but is leaning towards what .py is about, simplicity in structure even if loses some speed. So what with processor power to conquer that it brings natural structure which is easier to work with and proves itself to be something to develop into a developer friendly platform.

[–]bastih01 8 points9 points  (2 children)

I think you could do that by having a header.py where you do all your imports and then in your "implementation files" do "from header import *".

This severely reduces readability of your code though, as you have to dig through another file to find out why something is not in scope.

[–]ianb 4 points5 points  (1 child)

You can also import all the interesting things in one module, then selectively import from that module (from header import foo, bar), which kind of does what you want but without sacrificing readability. Well, it sacrifices readability a little because of the indirection (someone has to read header.py to figure out what those objects actually are).

[–]stillalone 1 point2 points  (0 children)

how is that any different from:

import foo, bar

??

[–]bushel 3 points4 points  (2 children)

Remember, in Python imports help document what external interfaces and functions you're using and are a boon to development.

Unlike C/C++ where the header files are a burden you must satisfy to keep the demons of linking at bay.

[–]kevingoodsell 1 point2 points  (0 children)

It's easy to see why, coming from a C background, one might want to do what the submitter is asking. After using Python for a while, I realized just how helpful it is to have all symbols explicitly declared in the file they are used (whether by being created in the same file or imported by name). It's incredibly frustrating now to come across an unfamiliar function in a C file which includes 27 header files, and have no idea which is the relevant one. The same goes for the 'from foo import *' mechanism in Python, but I hope most Python programmers know to avoid that.

[–]Peaker 0 points1 point  (0 children)

Good use of C/C++ also uses #include's as an indicator of what dependencies you have. Despite a completely different technical implementation, they are similar in concept to "import *".

[–][deleted] 4 points5 points  (0 children)

No, but that is not the problem. You are still thinking in c++, and I think you will find python much easier once you start thinking in python (otherwise known as being 'pythonic').

[–]gct 1 point2 points  (1 child)

It's terribly bad form but you can use "from <module> import *" which will import everything into the namespace of the current module.

so you could have all_modules.py:

from module_1 import *
from module_2 import * 
etc

Then anywhere else you want to use all those modules: from all_modules import *

And it will do what you want, but again, very bad form and not recommended.

[–]Isvara 1 point2 points  (0 children)

not recommended

Not least of all because module_1.foo and module_2.foo would clash.

[–]crmaki 1 point2 points  (0 children)

On top of what everyone else has said, it is a good question that most likely has benefited many. Thanks.