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

Unlock This Lesson

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

Unlock This Lesson

Hint: You can adjust the default video playback speed in your account settings.
Hint: You can set your subtitle preferences in your account settings.
Sorry! Looks like there’s an issue with video playback 🙁 This might be due to a temporary outage or because of a configuration issue with your browser. Please refer to our video player troubleshooting guide for assistance.

Circular Imports & How to Fix Them

In this lesson, you’ll learn what circular imports are and how to deal with problems caused by them.

00:00 Next, I would like to illustrate the example of a circular import. You’ll see on the left that I have a file called bar.py, which imports foo, which is on the right-hand side here.

00:10 You’ll see that I define a function called hello() in this method.

00:14 And on this side, we have foo.py, where we import hello() from bar, which is the file we were just in. We return hello() and we print whatever main() returns, which should be 'hello' in this case.

00:24 Let’s just quickly run this, so let’s run

00:29 foo.py.

00:32 ./foo.py. You’ll see that it can’t import hello(), for some reason. Why is that? If you notice here, that the first thing we do when we run bar is we go import foo. What that does, it goes over here and goes, “Okay, import bar from hello.” It goes back here, hits the first thing. It goes, “Hey, import foo,” goes back here. So we have a circular import that’s constantly going circular here, which is something we need to stop from happening. Now, this is just an unnecessary import that I use to illustrate the problem.

01:06 So by quickly, just deleting this, what should happen? It goes from bar import hello, loads the thing, hits hello(), loads it, main() should come back through, and prints the thing and we have 'hello' on our screen. So, let’s quickly just do that again.

01:22 Oh, did I not write the changes? Let’s go back.

01:26 We need to write. Excellent. Now let’s go back, run the file again, and then we have hello. So, circular imports are things of that nature.

01:37 Usually, a few ways of solving it is either move your import inside the function you’re calling, so if your global namespace is causing the conflict, or what you could do is reorganize your code structure so that the circular import no longer happens.

01:52 This usually happens when you have utility functions that are being used in multiple spots, and somehow you have something referring and importing multiple things.

02:01 So generally, keep a track of how your imports are going, and this is done by explicitly importing everything you need. So then you can just go through one-by-one looking at your imports and then finding the circular import.

02:13 This concludes our talk on Python imports. Hopefully, you learned a couple of things with the sys module and dir() that’ll allow you to inspect your scope, as well as a few tips and tricks on how to import implicitly and explicitly.

Alan ODannel on July 15, 2020

Nice overview. The Relative versus absolute cleared a few things up.

mckown on July 12, 2021

Nice overview. I especially appreciated how import, from..import, and from..import * affects SCOPE/NAMESPACES. And, as Alan commented, the relative vs absolute was a eye opener as well.

Become a Member to join the conversation.