Python: circular imports needed for type checking

circular-dependency, import, python

Solution

The best solution is to not check types.

The other solution is to not create an instance of, and not reference at all, `Foo` or `Bar` until both classes are loaded. If the first module is loaded first, don't create a `Bar` or refer to `Bar` until after the `class Foo` statement is executed. Similarly, if the second module is loaded first, don't create a `Foo` or reference `Foo` until after the `class Bar` statement is executed.

This is basically the source of the `ImportError`, which could be avoided if you did "import foo" and "import bar" instead, and used `foo.Foo` where you now use `Foo`, and `bar.Bar` where you now use `Bar`. In doing this, you no longer refer to either of them until a `Foo` or `Bar` is created, which hopefully won't happen until after both are created (or else you'll get an `AttributeError`).

Problem

First of all: I do know that there are already many questions and answers to the topic of the circular imports. The answer is more or less: "Design your Module/Class structure properly and you will not need circular imports". That is true. I tried very hard to make a proper design for my current project, I in my opinion I was successful with this. But my specific problem is the following: I need a type check in a module that is already imported by the module containing the class to check against. But this throws an import error. Like so: foo.py: ``` from bar import Bar class Foo(object): def __init__(self): self.__bar = Bar(self) ``` bar.py: ``` from foo import Foo class Bar(object): def __init__(self, arg_instance_of_foo): if not isinstance(arg_instance_of_foo, Foo): raise TypeError() ``` Solution 1: If I modified it to check the type by a string comparison, it will work. But I dont really like this solution (string comparsion is rather expensive for a simple type check, and could get a problem when it comes to refactoring). bar_modified.py: ``` from foo import Foo class Bar(object): def __init__(self, arg_instance_of_foo): if not arg_instance_of_foo.__class__.__name__ == "Foo": raise TypeError() ``` Solution 2: I could also pack the two classes into one module. But my project has lots of different classes like the "Bar" example, and I want to seperate them into different module files. After my own 2 solutions are no option for me: Has anyone a nicer solution for this problem?

Original source

Related problems