Circular (or cyclic) imports in Python

前端 未结 12 2366
醉梦人生
醉梦人生 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:38

    As other answers describe this pattern is acceptable in python:

    def dostuff(self):
         from foo import bar
         ...
    

    Which will avoid the execution of the import statement when the file is imported by other modules. Only if there is a logical circular dependency, this will fail.

    Most Circular Imports are not actually logical circular imports but rather raise ImportError errors, because of the way import() evaluates top level statements of the entire file when called.

    These ImportErrors can almost always be avoided if you positively want your imports on top:

    Consider this circular import:

    App A

    # profiles/serializers.py
    
    from images.serializers import SimplifiedImageSerializer
    
    class SimplifiedProfileSerializer(serializers.Serializer):
        name = serializers.CharField()
    
    class ProfileSerializer(SimplifiedProfileSerializer):
        recent_images = SimplifiedImageSerializer(many=True)
    

    App B

    # images/serializers.py
    
    from profiles.serializers import SimplifiedProfileSerializer
    
    class SimplifiedImageSerializer(serializers.Serializer):
        title = serializers.CharField()
    
    class ImageSerializer(SimplifiedImageSerializer):
        profile = SimplifiedProfileSerializer()
    

    From David Beazleys excellent talk Modules and Packages: Live and Let Die! - PyCon 2015, 1:54:00, here is a way to deal with circular imports in python:

    try:
        from images.serializers import SimplifiedImageSerializer
    except ImportError:
        import sys
        SimplifiedImageSerializer = sys.modules[__package__ + '.SimplifiedImageSerializer']
    

    This tries to import SimplifiedImageSerializer and if ImportError is raised, because it already is imported, it will pull it from the importcache.

    PS: You have to read this entire post in David Beazley's voice.

提交回复
热议问题