Locked learning resources

Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Locked learning resources

This lesson is for members only. Join us and get access to thousands of tutorials and a community of expert Pythonistas.

Unlock This Lesson

The import Statement

In this lesson, you’ll learn more about the import statement. Module contents are made available to the caller with the import statement. The import statement takes many different forms, as you’ll see below.

import <module_name>

The simplest form is the one you already saw:

Python
import <module_name>

Note that this does not make the module contents directly accessible to the caller. Each module has its own private symbol table, which serves as the global symbol table for all objects defined in the module. So, a module creates a separate namespace.

The statement import <module_name> only places <module_name> in the caller’s symbol table. The objects that are defined in the module remain in the module’s private symbol table.

From the caller, objects in the module are only accessible when prefixed with <module_name> via dot notation, as you’ll see below.

After the following import statement, mod is placed into the local symbol table. So, mod has meaning in the caller’s local context:

Python
>>> import mod
>>> mod
<module 'mod' from '/Users/chris/ModulesAndPackages/mod.py'>

But a, s, and printy() remain in the module’s private symbol table and are not meaningful in the local context:

Python
>>> a
Traceback (most recent call last):
  File "<input>", line 1, in <module>
    a
NameError: name 'a' is not defined
>>> s
Traceback (most recent call last):
  File "<input>", line 1, in <module>
    s
NameError: name 's' is not defined
>>> printy
Traceback (most recent call last):
  File "<input>", line 1, in <module>
    printy
NameError: name 'printy' is not defined

To be accessed in the local context, names of objects defined in the module must be prefixed by mod:

Python
>>> mod.a
[100, 200, 300]
>>> mod.s
'Computers are useless. They can only give you answers.'
>>> mod.printy('Hello')
arg = Hello

Several comma-separated modules may be specified in a single import statement:

Python
import <module_name>[, <module_name> ...]

from <module_name> import <name(s)>

An alternate form of the import statement allows individual objects from the module to be imported directly into the caller’s symbol table:

Python
from <module_name> import <name(s)>

Following execution of the above statement, <name(s)> can be referenced in the caller’s environment without the <module_name> prefix:

Python
>>> from mod import s, printy
>>> s
'Computers are useless. They can only give you answers.'
>>> printy('Hello')
arg = Hello

Because this form of import places the object names directly into the caller’s symbol table, any objects that already exist with the same name will be overwritten:

Python
>>> a = ['abc', 'def', 'ghi']
>>> a
['abc', 'def', 'ghi']
>>> from mod import a
>>> a
[100, 200, 300]

It is even possible to indiscriminately import everything from a module in one fell swoop:

Python
from <module_name> import *

This will place the names of all objects from <module_name> into the local symbol table, with the exception of any that begin with the underscore (_) character:

Python
>>> from mod import *
>>> s
'Computers are useless. They can only give you answers.'
>>> a
[100, 200, 300]
>>> printy
<function printy at 0x03B449C0>
>>> Classy
<class 'mod.Classy'>

This isn’t necessarily recommended in large-scale production code. It’s a bit dangerous because you’re entering names into the local symbol table en masse. Unless you know them all well and can be confident there won’t be a conflict, you have a decent chance of overwriting an existing name inadvertently.

However, this syntax is quite handy when you’re just mucking around with the interactive interpreter, for testing or discovery purposes, because it quickly gives you access to everything a module has to offer without a lot of typing.

from <module_name> import <name> as <alt_name>

It’s also possible to import individual objects but put them into the local symbol table with alternate names:

Python
from <module_name> import <name> as <alt_name>[, <name> as <alt_name> ]

This makes it possible to place names directly into the local symbol table but avoid conflicts with previously existing names:

Python
>>> a = ['abc', 'def', 'ghi']
>>> s = 'Hello There!'
>>> from mod import s as string, a as alist
>>> a
['abc', 'def', 'ghi']
>>> s
'Hello There!'
>>> string
'Computers are useless. They can only give you answers.'
>>> alist
[100, 200, 300]

import <module_name> as <alt_name>

You can also import an entire module under an alternate name:

Python
import <module_name> as <alt_name>

Here’s what that looks like in practice:

Python
>>> import mod as my_module
>>> my_module.a
[100, 200, 300]
>>> my_module.s
'Computers are useless. They can only give you answers.'

Module contents can be imported from within a function definition. In that case, the import does not occur until the function is called:

Python
>>> def importer():
...     from mod import printy
...     printy('Hello Everyone')
...

>>> mod
Traceback (most recent call last):
  File "<input>", line 1, in <module>
    mod
NameError: name 'mod' is not defined
>>> printy
Traceback (most recent call last):
  File "<input>", line 1, in <module>
    printy
NameError: name 'printy' is not defined
>>> importer()
arg = Hello Everyone

However, Python 3 does not allow the indiscriminate import * syntax from within a function:

Python
>>> def importer2():
...     from mod import *
  File "<bpython-input-11>", line 1
SyntaxError: import * only allowed at module level

Lastly, you can use a try statement with an except ImportError to guard against unsuccessful import attempts:

Python
>>> try:
...     # Non-existent module
...     import foo
... except ImportError:
...     print('Module not found')
...

Module not found

>>> try:
...     # Existing module, but non-existent object
...     from mod import bar
... except ImportError:
...     print('Object not found in module')
...

Object not found in module

00:00 In this video, you’ll take a deep dive into the import statement. So, what forms can the import statement take? In its simplest form, it’s like what you’ve already used in the previous video: import and then the module’s name. In that particular case, the module contents are not directly accessible to the caller, so you need to use dot notation.

00:21 The module creates a separate namespace. Let me show you what that looks like. Now, you’ve practiced this already, but you can type import mod and that would import your module. Now the trick to that is the objects that you’ve imported are not in the same local namespace—they’re not in the local symbol table.

00:39 So if you were to type the letter a, that object isn’t available. s isn’t available, printyany of those objects are not available.

00:46 You would need to use dot notation, beginning with the name of the module first. After adding the dot (.), now I can access a, or you could access s, or even printy().

01:02 As a note, you can also import multiple modules at a time, simply including a comma (,) in between the names of each.

01:13 As an alternative, individual objects from the module can be imported, like this: from, and then the module’s name, import, and then you’d use the objects’ names, where you can use several with commas (,) in between them.

01:27 The individual objects are directly accessible to the caller then. They’re imported directly into the caller’s symbol table, meaning you don’t have a separate namespace at that point.

01:37 Let me show you what that looks like. I exited and restarted the REPL here. In the second example, you’d say from, and then the module’s name, import, and then you would say, “Oh, I want s and printy.” So now, those have been imported into the local symbol table. s is actually available, and so is printy()

02:03 in the local namespace, not requiring you to use dot notation. There is a need to be careful, though. If you were to create an object name a, and let’s say a has a few text strings in a list.

02:17 There’s a. If you were to import a from your module, what happened to the existing local a? Well, it’s been overwritten. And so this creates a collision, if you will, overwriting the existing object.

02:32 So there’s a need to be careful with the namespaces here in simple, generic names. Now, it is also possible to import everything from a module at once. In that case, it would be from, and then the module’s name, import, and then an asterisk sign (*).

02:46 You probably have seen this before in a script or two, but this places all the names of the objects into the local symbol table. The only thing that won’t be imported is anything that begins with an underscore (_), keeping it private to the module itself.

03:01 This isn’t necessarily recommended. Unless you know all the names are not going to conflict with or overwrite any existing names, you can run into some trouble.

03:12 This will take all the named objects from the module into the local symbol table. So now, Classy is there, printy(),

03:26 and the string object s. I’m going to exit again. You can also import individual objects and then have them have an alternative name. That would look like this: from module import, whatever the object’s name is, and then as what you’d like the object to be renamed as.

03:45 And you can do this multiple times. It’s making it possible to place names directly into the local symbol table, therefore it could avoid conflicts with existing names.

03:55 You still need to be careful with whatever you choose as alternative names. In this example, say you have local variables that are named a,

04:08 and another one named s, which is a string. Here’s the two objects, a and s, so if you were to import a and s from your module, it would write over these two.

04:18 What you can do is say from mod import s and give it a new name—maybe name it just string. And a as alist. So again, you can use this comma (,) to do multiple imports at once.

04:29 So now a is still there and s is still there, but string is what you imported, and alist is also what you imported from the module.

04:42 Another possibility is to import the entire module under an alternative name. In this case, you’d say import <module> as what you’d like that other name to be. A common one would be import pandas as pd, therefore not having to spell it all the way out.

04:55 If a module has a really long name, some people like to shorten it. You would say import mod as and then you’d give it a different name. So name it, say, my_module. So now my_module is here and it has a and s.

05:13 Modules can also be imported from within a function. Let me show you what that looks like. In this last example, create a function. I’ll have you name it importer().

05:25 Inside the function, you could say from mod import printy, and then use printy()

05:36 inside of it. So right now, mod isn’t here and printy isn’t available, but if you run importer() and call that function, it imported printy() from the module mod, and then called it with the argument 'Hello Everyone'.

05:53 One note here, if you were to try to use the indiscriminate asterisk sign (*) to try to import everything, it’ll let you know that the import * is only allowed at the module level.

06:07 You can’t do it inside of a function. You can have problems if the module is not available to import. Another safer way to do this is to use a try statement with an except.

06:19 So, what does that look like? You start with try:, and let’s say this is a non-existent module.

06:36 And you can see here, that module was not found. Try it one more time, in this case with an existing module that doesn’t have an existent object—say it’s missing a particular object that you were looking for.

06:53 In the except statement you could say then, “Okay, that object was not found inside the module,” therefore guarding against unsuccessful imports here. So in this case, it looked inside mod and didn’t find bar. Next up, you’ll check out the dir() function.

Avatar image for gagejesse

gagejesse on Jan. 30, 2020

I dunno how you managed to provide a thorough tutorial on exactly what I needed, two days before I needed it, but I certainly appreciate it. Thank you!

Avatar image for David Masterson

David Masterson on March 1, 2022

Hello everyone! I am not a complete newb to python but I am still suffering from newb related issues. It never fails. I have been coding a script and running it and it it runs fine until the dreaded import statement rears it’s ugly head. I am trying to import a module into another module that is 2 directories deeper. Here is my folder structure

(www.facebook.com/photo/?fbid=143929091441840&set=gm.1633934173623401) I am trying to import the api_methods.py into the positions.py module and I keep getting this error “attempted relative import with no known parent package”. The import statement I am using is from … import alpaca_api import api_methods please help me understand why this keeps happening so I can code knowing that my imports are going to work. Lastly I am coding in VSCode with my python path set to the virtual env python3.8 bin. I have ran the repl bpython and looked at what name is and it is ‘main’ and package comes back with nothing. I have watched all the videos on relative and absolute imports but it keeps returning a ‘no module named apis’ when doing absolute import and the ‘attempted relative import with no known parent package’ when using relative import. Any help would be greatly appreciated as this has been a blocker for a few days, and I am always facing this issue when trying to organize my folder structure.

Become a Member to join the conversation.