Circular (or cyclic) imports in Python

前端 未结 12 2649
醉梦人生
醉梦人生 2020-11-21 05:23

What will happen if two modules import each other?

To generalize the problem, what about the cyclic imports in Python?

12条回答
  •  清歌不尽
    2020-11-21 05:39

    There are a lot of great answers here. While there are usually quick solutions to the problem, some of which feel more pythonic than others, if you have the luxury of doing some refactoring, another approach is to analyze the organization of your code, and try to remove the circular dependency. You may find, for example, that you have:

    File a.py

    from b import B
    
    class A:
        @staticmethod
        def save_result(result):
            print('save the result')
    
        @staticmethod
        def do_something_a_ish(param):
            A.save_result(A.use_param_like_a_would(param))
    
        @staticmethod
        def do_something_related_to_b(param):
            B.do_something_b_ish(param)
    

    File b.py

    from a import A
    
    class B:
        @staticmethod
        def do_something_b_ish(param):
            A.save_result(B.use_param_like_b_would(param))
    

    In this case, just moving one static method to a separate file, say c.py:

    File c.py

    def save_result(result):
        print('save the result')
    

    will allow removing the save_result method from A, and thus allow removing the import of A from a in b:

    Refactored File a.py

    from b import B
    from c import save_result
    
    class A:
        @staticmethod
        def do_something_a_ish(param):
            A.save_result(A.use_param_like_a_would(param))
    
        @staticmethod
        def do_something_related_to_b(param):
            B.do_something_b_ish(param)
    

    Refactored File b.py

    from c import save_result
    
    class B:
        @staticmethod
        def do_something_b_ish(param):
            save_result(B.use_param_like_b_would(param))
    

    In summary, if you have a tool (e.g. pylint or PyCharm) that reports on methods that can be static, just throwing a staticmethod decorator on them might not be the best way to silence the warning. Even though the method seems related to the class, it might be better to separate it out, especially if you have several closely related modules that might need the same functionality and you intend to practice DRY principles.

提交回复
热议问题