Python circular importing?

后端 未结 7 1033
不知归路
不知归路 2020-11-22 05:46

So i\'m getting this error

Traceback (most recent call last):
  File \"/Users/alex/dev/runswift/utils/sim2014/simulator.py\", line 3, in 
    f         


        
相关标签:
7条回答
  • 2020-11-22 06:16

    When you import a module (or a member of it) for the first time, the code inside the module is executed sequentially like any other code; e.g., it is not treated any differently that the body of a function. An import is just a command like any other (assignment, a function call, def, class). Assuming your imports occur at the top of the script, then here's what's happening:

    • When you try to import World from world, the world script gets executed.
    • The world script imports Field, which causes the entities.field script to get executed.
    • This process continues until you reach the entities.post script because you tried to import Post
    • The entities.post script causes physics module to be executed because it tries to import PostBody
    • Finally, physics tries to import Post from entities.post
    • I'm not sure whether the entities.post module exists in memory yet, but it really doesn't matter. Either the module is not in memory, or the module doesn't yet have a Post member because it hasn't finished executing to define Post
    • Either way, an error occurs because Post is not there to be imported

    So no, it's not "working further up in the call stack". This is a stack trace of where the error occurred, which means it errored out trying to import Post in that class. You shouldn't use circular imports. At best, it has negligible benefit (typically, no benefit), and it causes problems like this. It burdens any developer maintaining it, forcing them to walk on egg shells to avoid breaking it. Refactor your module organization.

    0 讨论(0)
  • 2020-11-22 06:17

    I was able to import the module within the function (only) that would require the objects from this module:

    def my_func():
        import Foo
        foo_instance = Foo()
    
    0 讨论(0)
  • 2020-11-22 06:18

    I was using the following:

    from module import Foo
    
    foo_instance = Foo()
    

    but to get rid of circular reference I did the following and it worked:

    import module.foo
    
    foo_instance = foo.Foo()
    
    0 讨论(0)
  • 2020-11-22 06:20

    I think the answer by jpmc26, while by no means wrong, comes down too heavily on circular imports. They can work just fine, if you set them up correctly.

    The easiest way to do so is to use import my_module syntax, rather than from my_module import some_object. The former will almost always work, even if my_module included imports us back. The latter only works if my_object is already defined in my_module, which in a circular import may not be the case.

    To be specific to your case: Try changing entities/post.py to do import physics and then refer to physics.PostBody rather than just PostBody directly. Similarly, change physics.py to do import entities.post and then use entities.post.Post rather than just Post.

    0 讨论(0)
  • 2020-11-22 06:24

    For those of you who, like me, come to this issue from Django, you should know that the docs provide a solution: https://docs.djangoproject.com/en/1.10/ref/models/fields/#foreignkey

    "...To refer to models defined in another application, you can explicitly specify a model with the full application label. For example, if the Manufacturer model above is defined in another application called production, you’d need to use:

    class Car(models.Model):
        manufacturer = models.ForeignKey(
            'production.Manufacturer',
            on_delete=models.CASCADE,
    )
    

    This sort of reference can be useful when resolving circular import dependencies between two applications...."

    0 讨论(0)
  • 2020-11-22 06:27

    If you run into this issue in a fairly complex app it can be cumbersome to refactor all your imports. PyCharm offers a quickfix for this that will automatically change all usage of the imported symbols as well.

    0 讨论(0)
提交回复
热议问题