简体   繁体   中英

Module 'a' has no attribute 'b' while importing module from same directory

I have following directory structure in my Python project:

    - dump_specs.py
    /impa
        - __init__.py
        - server.py
        - tasks.py

I had a problem with circular references. dump_specs.py needs a reference to app from server.py . server.py is a Flask app which needs a references to celery tasks from tasks.py . So dump_specs.py looks like:

#!/usr/bin/env python3

import impa.server

def dump_to_dir(dir_path):
    # Do something
    client = impa.server.app.test_client()
    # Do the rest of things

impa/server.py looks like:

#!/usr/bin/env python3

import impa.tasks

app = Flask(__name__)

# Definitions of endpoints, some of them use celery tasks -
# that's why I need impa.tasks reference

And impa/tasks.py :

#!/usr/bin/env python3

from celery import Celery

import impa.server

def make_celery(app):
    celery = Celery(app.import_name,
                broker=app.config['CELERY_BROKER_URL'],
                backend=app.config['CELERY_RESULT_BACKEND'])
    TaskBase = celery.Task

    class ContextTask(TaskBase):
        abstract = True

        def __call__(self, *args, **kwargs):
            with app.app_context():
                return TaskBase.__call__(self, *args, **kwargs)

    celery.Task = ContextTask
    return celery

celery = make_celery(impa.server.app)

When I'm trying to dump specs with ./dump_specs.py I've got an error:

./dump_specs.py specs
Traceback (most recent call last):
  File "./dump_specs.py", line 9, in <module>
    import impa.server
  File "/build/impa/server.py", line 23, in <module>
    import impa.tasks
  File "/build/impa/tasks.py", line 81, in <module>
    celery = make_celery(impa.server.app)
    AttributeError: module 'impa' has no attribute 'server'

And I can't understand what's wrong. Could someone explain what's happening and how to get rid of this error?

If I have managed to reproduce your problem correctly on my host, it should help youto insert import impa.tasks into dump_specs.py above import impa.server .

The way your modules depend on each other, the loading order is important. IIRC (the loading machinery is described in greater details in the docs), when you first try to import impa.server , it will on line 23 try to import impa.tasks , but import of impa.server is not complete at this point. There is import impa.server in impa.tasks , but we do not got back and import it at this time (we'd otherwise end up in a full circle) and continue importing impa.tasts until we want to access impa.server.app , but we haven't gotten to the point we could do that yet, impa.server has not been imported yet.

When possible, it would also help if the code accessing another module in your package wasn't executed on import (directly called as part of the modules instead of being in a function or a class which would be called/used after the imports have completed).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM