8

I am not very clear on this aspect. Let's say you have a bunch of .py files that are their own separate modules.

Why does each .py file need to import the others when they use that class? Or do they? Because I was pretty sure that other languages (Java, for instance), did not require import when referring to classes/files in the same directory. I might be wrong.

0

5 Answers 5

8

Simply put, that is the way it was designed. You mentioned Java as a counter example - the Java language designers wanted to make classloading somewhat implicit, so they check the same directory before throwing ClassNotFound. Outside of that you need to qualify, just like in Python.

As Tom Anderson said, C does the same thing as Python, and it's a compiled language. Perhaps the interpreted nature of the language had something to do with the final decision (for performance, explicitness, etc.), but in the end it's up to the developer.

3
  • I'm not sure that, "that is the way it was designed" is really answer to this question. Dec 31, 2011 at 0:39
  • 2
    -1: I don't know Python well, but my understanding is that you have to import a package to use anything in it in Python. In Java, you don't technically ever have to use import statements; you could just write out the full, qualified names of classes, etc. in other packages.
    – compman
    Dec 31, 2011 at 20:44
  • 1
    Qualification is resolving the path to an object (class, function, whatever). Whether it is done by imports or syntax qualifiers is irrelevant.
    – Michael K
    Jan 2, 2012 at 6:03
3

Because python is interpreted everything you import is available at the prompt. Java (and C++) have a compile and link step which can search out and include only functions that are used

If everything was automatically imported there would be 1000s of functions and variables and it would be impossible to type anything without colliding with one.

edit: Ok it's a little more than just compiled vs interpreted. Python is intended as a "batteries included" language - there are libraries available to do almost everything. Since you are only ever going to use a small fraction of those there needs to be a way of organising them so that you only include those you need.

The import from syntax is clever because you can either import the whole library and keep Java-like fully qualified names or you can import specific functions (or all functions) into the local namespace

>>>import math
>>> math.sin(0)  #no confusion with any other 'sin'

>>> from math import sin  # or import *
>>> sin(0) # makes equations with sin shorter and simpler

The second reason is is especially important in a dynamic language like python. Since you don't have to define variables before you use them it would be difficult for the environment to work out if sin is the maths function or a variable of yours in an interpreter.

9
  • I don't get it... Could you explain it for a newb? :( Dec 30, 2011 at 7:11
  • @ChuckTesta To fully understand the difference discusssed in this answer, you need to understand the difference between compiled and interpreted languages - this blog post sums it up in quite simple terms: blog.julipedia.org/2004/07/…
    – Bob
    Dec 30, 2011 at 10:14
  • 8
    The difference has absolutely nothing to do with interpreted vs compiled. You could write a Python compiler and would have to work exactly the same way as the Python interpreter. The difference is simply that the designers of Java (say) decided to add implicit loading of classes from other files, and the designer(s) of Python didn't. Note that C is compiled, but has essentially the same rules as Python - you can't use a function from another file unless you #include a header for it and link the right library. Dec 30, 2011 at 12:45
  • 2
    The point is valid: implicit class loading would have a big runtime cost in an interpreted language Dec 30, 2011 at 14:11
  • 1
    @Simon, why would it have a big runtime cost? Dec 31, 2011 at 0:16
1

Imagine you had this code in python:

foo = MyObject()
fo.bar()

Obviously, we've got a typo and fo should have been foo. Right now python says:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'fo' is not defined

But with implicit class loading it might say:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named fo

which would be confusing. Worse yet, if you misspelled a variable name that just happened to be the name of a module, you would get an even more confusing error as you tried to treat that module as if it were your variable. Python can't tell whether something is a class name, object or whatever.

Java, on the other hand, I believe can tell from the syntax whether a certain identifier refers to a class or something else. Thus it has no problem with producing an appropriate error message.

Overall, it fits into the Python philosophy of being explicit rather then implicit. They figure its better to explicitly import a module rather than have it imported automatically. The error message issue is factor that plays into the decision.

Some have suggested that there would be a large runtime cost to implicit imports. I don't think so. What happens is something like this:

  1. LOAD_GLOBAL opcode invoked with name "foo"
  2. globals dictionary checked for "foo"
  3. builtins dictionary checked for "foo"
  4. If foo found, store in globals and continue on
  5. If foo not found, raise NameError

To support implicit module loading we could do:

  1. LOAD_GLOBAL opcode invoked with name "foo"
  2. globals dictionary checked for "foo"
  3. builtins dictionary checked for "foo"
  4. if the above fail, try import foo
  5. If foo found, store in globals and continue on
  6. If foo not found, raise NameError

The first time the module is used, it would take a bit longer because it has to search through other dictionaries first. But that's only the first time, and shouldn't be significant in terms of whole program runtime.

There would be a significant cost, in the case of misspelled variable names. When they occour, python would waste time reading the disk trying to find the module. But if that happens your program is about to die with a traceback anyways and the performance isn't a big concern.

1

There are some important differences between Python and Java; while Java has a "one class per file" rule, Python does not. Also, not everything in Python is a class.

So a module can have classes, functions, and just plain old variables -- usually all related in some way (such as random functions in random, math routines in math, string contstants in string, etc).

If you want to access any of classes/function/variables from a particular module, you must first import it.

Why is this a Good Thing?

  • Keeps module name spaces clean (not cluttered with names you will never use)
  • Easier to track back to the appropriate module when something goes wrong
  • Allows you to use names without fear of either an error because the name is in use, or clobbering the already in-use name (you can have math.sin and your own sin functions)
  • Helps clarify program structure.
1

One of the most important concepts in Python is that of namespaces (do import this at the prompt some time to find out what the others are). I know that namespaces exist in other languages too, but in Python you only have access to the current namespace, which is what's defined in the current module. To get access to other identifiers, you need to import them into the current namespace: either by importing their containing module (the import foo syntax) or the names themselves (from foo import bar).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.