0

Possible Duplicate:
Python: Circular (or cyclic) imports

I'm new to Python, and I'm having an issue, but I'm not exactly sure if this is my issue. I have two files, user.py and comments.py. In user.py, I do

from comments import Comment

and in comments.py I do

from user import User

My user loads fine, but when I load the URL that leads to comments, I get a server error. Commenting out the from comments import Comment fixes the problem. Am I doing something wrong?

Community
  • 1
  • 1
Snowman
  • 31,411
  • 46
  • 180
  • 303

2 Answers2

1

Yes, you have a circular import, and those cause many many problems. If you think about what is actually happening when you import, it is analogous to saying, "copy the code from file x in to this file," but if you copy from x to y then back from y to x, you've created an infinite loop where it's difficult to impossible for the interpreter to figure out which module is supposed to supersede or load which in which situations. However, if your program is architected properly, you should not have any. What reason do you have for having this circular import? Chances are you don't actually need it at all if we look at the problem a little more carefully.

Silas Ray
  • 25,682
  • 5
  • 48
  • 63
  • Well both files need each other. Is there no way to fix this? – Snowman Apr 16 '12 at 22:27
  • 3
    @mohabitar: Yes, fix your design. – Sven Marnach Apr 16 '12 at 22:27
  • Thank you for your insight Sven. Anyway, I thought I would just organize my code in to two separate files. I don't want functions related to User to be in the same file as functions related to Comments. So I separated them. But since a User can post comments, and a Comment needs a user, I do need to reference them. Is there a better way to do this? – Snowman Apr 16 '12 at 22:30
  • @mohabitar If you have a proper design, your modules should start to have a pattern of producer/datasource > user/consumer. This chain can continue for multiple levels, but by having your project organized this way, responsibility for what code does what becomes much clearer and problems like circular imports go away for the most part. – Silas Ray Apr 16 '12 at 22:30
  • 1
    @mohabitar Is a comment owned by a user, or does a comment have a user that made it? Unless there is a very compelling reason for having the relationship be bidirectional, having that linkage only made once is probably the better way to go. What data does the user need from comment and vice versa? – Silas Ray Apr 16 '12 at 22:32
  • Thanks, I was able to clean my code up a little and fix the issue. – Snowman Apr 16 '12 at 22:41
1

This kind of circular import does not work. Importing a module means essentially executing the statements in it. The import statements are executed in the moment they are encountered, so in at least one of the modules the other module has not yet been initialised, so the import will fail.

A circular dependency is considered an antipattern. There are situations where they somehow occur naturally, but in general they are a sign of a bad design.

You can probably make this work by moving one of the import statements to the end of the module or to function level, but I'd recommend against these "fixes".

Sven Marnach
  • 574,206
  • 118
  • 941
  • 841