Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Circular dependency between python classes

Tags:

python

In python, class definitions could depend on each other like this:

 # This is not fine
 class A():
     b = B().do_sth();
     def do_sth(self):
         pass

 class B():
     a = A().do_sth();
     def do_sth(self):
         pass

 # This is fine
 def FuncA():
     b = FuncB()

 def FuncB():
     a = FuncA()
  1. Why does clases have this problem, while functions don't?
  2. Languages like C++ have declarations: class B to resolve this kind of dependency, does python have similar constructs?
like image 665
NeoWang Avatar asked Apr 12 '14 05:04

NeoWang


People also ask

How does python handle circular dependencies?

Importing Python Modules is a great article that explains circular imports in Python. The easiest way to fix this is to move the path import to the end of the node module. By the way, is there some reason other than you "liking" it that you want one class per module?

How do I fix the circular import error in python?

Change Name of working python script: Changing the name of the Working file different from the module which is imported in the script can avoid the Circular Imports problem. Import the module: Avoid importing objects or functions from a module that can cause Circular Imports.

How do you avoid circular dependencies in python?

You can, however, use the imported module inside functions and code blocks that don't get run on import. Generally, in most valid cases of circular dependencies, it's possible to refactor or reorganize the code to prevent these errors and move module references inside a code block.

How do you resolve circular dependency issues?

The best solution is to avoid circular dependencies, of course, but it you're truly stuck, you can work around the issue by using property injection and RegisterInstance<T>(T t) (or its equivalent, if you're not using Autofac).


2 Answers

In the function case, we don't actually have to call FuncB to define FuncA. FuncB only needs to be called when we actually call FuncA.

Unlike with functions, the body of a class is executed at definition time. To define class A, we need to actually call a B method, which we can't do because class B isn't defined yet.

To work around this, we can define the classes and then add the properties afterward:

class A(object):
    ...

class B(object):
    ...

A.b = B.do_sth()
B.A = A.do_sth()

If each do_sth call relies on the other call already having been executed, though, this resolution won't work. You will need to perform more extensive changes to fix the problem.

like image 124
user2357112 supports Monica Avatar answered Oct 16 '22 15:10

user2357112 supports Monica


  1. Classes have these problems because directives on the class level (b = B.do_smth()) are executed while defining the class, not when you create an instance of the class
  2. You may complete the definition of a class lately, after both classes are defined. Python is a dynamic language after all.
like image 24
user3159253 Avatar answered Oct 16 '22 15:10

user3159253