根据以下示例,我目前正在使用后端api:https://github.com/gothinkster/flask-realworld-example-app
我是python的新手,在导入工作方面遇到了问题。我根本不理解python基于导入功能的不一致性而遵循的导入规则。在某些情况下,导入词可以罚款,但在其他情况下则不能。
api / user / serializers.py:
# coding: utf-8
from marshmallow import Schema, fields, pre_load, post_dump
from api.utils import must_not_be_blank
class UserSchema(Schema):
username = fields.Str(validate=[must_not_be_blank])
email = fields.Email(validate=[must_not_be_blank])
password = fields.Str(validate=[must_not_be_blank], load_only=True)
...
api / utils.py:
# -*- coding: utf-8 -*-
"""Helper utilities and decorators."""
from api.user.models import User # noqa
from marshmallow import ValidationError
import re
def jwt_identity(payload):
return User.get_by_id(payload)
def identity_loader(user):
return user.id
def must_not_be_blank(data):
if not data:
raise ValidationError('Data not provided.')
def contains_only_letters(data):
if not re.match("^[a-zA-Z]+(([',. -][a-zA-Z ])?[a-zA-Z]*)*$", str(data)):
raise ValidationError('Invalid String')
def validate_uga_id(uga_id):
if uga_id.isdigit() is False:
raise ValidationError('Not a valid UGA ID')
def validate_phone_number(phone_number):
if not re.match(r"^(\+\d{1,2}\s)?\(?\d{3}\)?[\s.-]\d{3}[\s.-]\d{4}$", phone_number):
raise ValidationError('Invalid phone number')
我遇到的问题出现在“ serializers”文件中。一旦我运行api并尝试调用API的/ login /路径,它就会尝试调用序列化程序,然后出现以下错误:
File "/Users/Shawn/Desktop/Computer Science/CSCI4050 Software Engineering/flask-realworld-example-app/api/user/serializers.py", line 3, in <module>
from api.utils import must_not_be_blank
ImportError: cannot import name 'must_not_be_blank'
此导入可在其他地方使用。例如,在app / extensions.py中,导入有效,但前提是我将其放在jwt变量前面。如果我将导入放在顶部,那么我将收到一个错误消息,即“ db”无法在其他地方导入:
# -*- coding: utf-8 -*-
"""Extensions module. Each extension is initialized in the app factory located in app.py."""
from flask_bcrypt import Bcrypt
from flask_caching import Cache
from flask_cors import CORS
from flask_jwt_extended import JWTManager
from flask_migrate import Migrate
from flask_sqlalchemy import SQLAlchemy, Model
class CRUDMixin(Model):
"""Mixin that adds convenience methods for CRUD (create, read, update, delete) operations."""
@classmethod
def create(cls, **kwargs):
"""Create a new record and save it the database."""
instance = cls(**kwargs)
return instance.save()
def update(self, commit=True, **kwargs):
"""Update specific fields of a record."""
for attr, value in kwargs.items():
setattr(self, attr, value)
return commit and self.save() or self
def save(self, commit=True):
"""Save the record."""
db.session.add(self)
if commit:
db.session.commit()
return self
def delete(self, commit=True):
"""Remove the record from the database."""
db.session.delete(self)
return commit and db.session.commit()
# A storage engine to save revoked tokens. In production if
# speed is the primary concern, redis is a good bet. If data
# persistence is more important for you, postgres is another
# great option. In this example, we will be using an in memory
# store, just to show you how this might work. For more
# complete examples, check out these:
# https://github.com/vimalloc/flask-jwt-extended/blob/master/examples/redis_blacklist.py
# https://github.com/vimalloc/flask-jwt-extended/tree/master/examples/database_blacklist
blacklist = set()
bcrypt = Bcrypt()
db = SQLAlchemy(model_class=CRUDMixin)
migrate = Migrate()
cache = Cache()
cors = CORS()
from api.utils import jwt_identity, identity_loader # noqa
jwt = JWTManager()
jwt.user_loader_callback_loader(jwt_identity)
jwt.user_identity_loader(identity_loader)
# For this example, we are just checking if the tokens jti
# (unique identifier) is in the blacklist set. This could
# be made more complex, for example storing all tokens
# into the blacklist with a revoked status when created,
# and returning the revoked status in this call. This
# would allow you to have a list of all created tokens,
# and to consider tokens that aren't in the blacklist
# (aka tokens you didn't create) as revoked. These are
# just two options, and this can be tailored to whatever
# your application needs.
@jwt.token_in_blacklist_loader
def check_if_token_in_blacklist(decrypted_token):
jti = decrypted_token['jti']
return jti in blacklist
完整跟踪:
Traceback (most recent call last):
File "/Users/Shawn/Desktop/Computer Science/CSCI4050 Software Engineering/flask-realworld-example-app/autoapp.py", line 5, in <module>
from api.app import create_app
File "/Users/Shawn/Desktop/Computer Science/CSCI4050 Software Engineering/flask-realworld-example-app/api/app.py", line 4, in <module>
from api.extensions import bcrypt, cache, db, migrate, jwt, cors
File "/Users/Shawn/Desktop/Computer Science/CSCI4050 Software Engineering/flask-realworld-example-app/api/extensions.py", line 55, in <module>
from api.utils import jwt_identity, identity_loader # noqa
File "/Users/Shawn/Desktop/Computer Science/CSCI4050 Software Engineering/flask-realworld-example-app/api/utils.py", line 3, in <module>
from api.user.models import User # noqa
File "/Users/Shawn/Desktop/Computer Science/CSCI4050 Software Engineering/flask-realworld-example-app/api/user/__init__.py", line 3, in <module>
from . import views # noqa
File "/Users/Shawn/Desktop/Computer Science/CSCI4050 Software Engineering/flask-realworld-example-app/api/user/views.py", line 14, in <module>
from .serializers import user_schema
File "/Users/Shawn/Desktop/Computer Science/CSCI4050 Software Engineering/flask-realworld-example-app/api/user/serializers.py", line 3, in <module>
from api.utils import must_not_be_blank
ImportError: cannot import name 'must_not_be_blank'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/Users/Shawn/Desktop/Computer Science/CSCI4050 Software Engineering/flask-realworld-example-app/venv/lib/python3.6/site-packages/flask/cli.py", line 338, in __call__
self._flush_bg_loading_exception()
File "/Users/Shawn/Desktop/Computer Science/CSCI4050 Software Engineering/flask-realworld-example-app/venv/lib/python3.6/site-packages/flask/cli.py", line 326, in _flush_bg_loading_exception
reraise(*exc_info)
File "/Users/Shawn/Desktop/Computer Science/CSCI4050 Software Engineering/flask-realworld-example-app/venv/lib/python3.6/site-packages/flask/_compat.py", line 39, in reraise
raise value
File "/Users/Shawn/Desktop/Computer Science/CSCI4050 Software Engineering/flask-realworld-example-app/venv/lib/python3.6/site-packages/flask/cli.py", line 314, in _load_app
self._load_unlocked()
File "/Users/Shawn/Desktop/Computer Science/CSCI4050 Software Engineering/flask-realworld-example-app/venv/lib/python3.6/site-packages/flask/cli.py", line 330, in _load_unlocked
self._app = rv = self.loader()
File "/Users/Shawn/Desktop/Computer Science/CSCI4050 Software Engineering/flask-realworld-example-app/venv/lib/python3.6/site-packages/flask/cli.py", line 388, in load_app
app = locate_app(self, import_name, name)
File "/Users/Shawn/Desktop/Computer Science/CSCI4050 Software Engineering/flask-realworld-example-app/venv/lib/python3.6/site-packages/flask/cli.py", line 247, in locate_app
"\n\n{tb}".format(name=module_name, tb=traceback.format_exc())
flask.cli.NoAppException: While importing "autoapp", an ImportError was raised:
Traceback (most recent call last):
File "/Users/Shawn/Desktop/Computer Science/CSCI4050 Software Engineering/flask-realworld-example-app/venv/lib/python3.6/site-packages/flask/cli.py", line 240, in locate_app
__import__(module_name)
File "/Users/Shawn/Desktop/Computer Science/CSCI4050 Software Engineering/flask-realworld-example-app/autoapp.py", line 5, in <module>
from api.app import create_app
File "/Users/Shawn/Desktop/Computer Science/CSCI4050 Software Engineering/flask-realworld-example-app/api/app.py", line 4, in <module>
from api.extensions import bcrypt, cache, db, migrate, jwt, cors
File "/Users/Shawn/Desktop/Computer Science/CSCI4050 Software Engineering/flask-realworld-example-app/api/extensions.py", line 55, in <module>
from api.utils import jwt_identity, identity_loader # noqa
File "/Users/Shawn/Desktop/Computer Science/CSCI4050 Software Engineering/flask-realworld-example-app/api/utils.py", line 3, in <module>
from api.user.models import User # noqa
File "/Users/Shawn/Desktop/Computer Science/CSCI4050 Software Engineering/flask-realworld-example-app/api/user/__init__.py", line 3, in <module>
from . import views # noqa
File "/Users/Shawn/Desktop/Computer Science/CSCI4050 Software Engineering/flask-realworld-example-app/api/user/views.py", line 14, in <module>
from .serializers import user_schema
File "/Users/Shawn/Desktop/Computer Science/CSCI4050 Software Engineering/flask-realworld-example-app/api/user/serializers.py", line 3, in <module>
from api.utils import must_not_be_blank
ImportError: cannot import name 'must_not_be_blank'
答案 0 :(得分:1)
此回溯清楚地表明发生了什么:
Traceback (most recent call last):
File "/Users/Shawn/Desktop/Computer Science/CSCI4050 Software Engineering/flask-realworld-example-app/autoapp.py", line 5, in <module>
from api.app import create_app
File "/Users/Shawn/Desktop/Computer Science/CSCI4050 Software Engineering/flask-realworld-example-app/api/app.py", line 4, in <module>
from api.extensions import bcrypt, cache, db, migrate, jwt, cors
File "/Users/Shawn/Desktop/Computer Science/CSCI4050 Software Engineering/flask-realworld-example-app/api/extensions.py", line 55, in <module>
from api.utils import jwt_identity, identity_loader # noqa
File "/Users/Shawn/Desktop/Computer Science/CSCI4050 Software Engineering/flask-realworld-example-app/api/utils.py", line 3, in <module>
from api.user.models import User # noqa
File "/Users/Shawn/Desktop/Computer Science/CSCI4050 Software Engineering/flask-realworld-example-app/api/user/__init__.py", line 3, in <module>
from . import views # noqa
File "/Users/Shawn/Desktop/Computer Science/CSCI4050 Software Engineering/flask-realworld-example-app/api/user/views.py", line 14, in <module>
from .serializers import user_schema
File "/Users/Shawn/Desktop/Computer Science/CSCI4050 Software Engineering/flask-realworld-example-app/api/user/serializers.py", line 3, in <module>
from api.utils import must_not_be_blank
ImportError: cannot import name 'must_not_be_blank'
有这个:
File "/Users/Shawn/Desktop/Computer Science/CSCI4050 Software Engineering/flask-realworld-example-app/api/extensions.py", line 55, in <module>
from api.utils import jwt_identity, identity_loader # noqa
并最终执行以下操作:
File "/Users/Shawn/Desktop/Computer Science/CSCI4050 Software Engineering/flask-realworld-example-app/api/user/serializers.py", line 3, in <module>
from api.utils import must_not_be_blank
换句话说,from api.utils import must_not_be_blank
是在已经导入api.utils
的情况下执行的。此时,api.utils
已完成一半,从中导入内容可能会失败。而且确实失败了。
这称为循环导入。您应该重新组织代码,以便没有循环导入,即,如果A
导入B
和B
导入C
,则C
不应导入A
或B
。
答案 1 :(得分:0)
很可能由于某些模块之间的circular dependency而发生。最简单的检查方法是查看整个项目的依赖关系图。