[英]Unable to import method from another python file
I am currently working on a backend api based off of this example: https://github.com/gothinkster/flask-realworld-example-app我目前正在基于以下示例开发后端 api: https://github.com/gothinkster/flask-realworld-example-app
I am new to python and I am having an issue with getting imports to work.我是 python 的新手,我遇到了让导入工作的问题。 I am simply not understanding the import rules that python follows based on the inconsistencies that I am noticing in the ability to import the necessary functions.
我根本不理解 python 遵循的导入规则,因为我注意到导入必要功能的能力存在不一致。 In certain cases the imports word fine, but then in others it does not.
在某些情况下,导入词很好,但在其他情况下则不然。
api/user/serializers.py: api/用户/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: 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')
The issue I am having is occuring inside of the "serializers" file.我遇到的问题发生在“序列化程序”文件中。 Once I run the api and try to to call the /login/ path of my API, it tries to call the serializer and then I get the following error:
一旦我运行 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'
This import works in other places though.但是,此导入在其他地方也有效。 For example in the app/extensions.py the import works but only if I put it right in front of the jwt variable.
例如,在 app/extensions.py 中,导入有效,但前提是我将它放在 jwt 变量的前面。 If I put the import at the top, then I got an error that "db" could not be imported in other places:
如果我将导入放在顶部,那么我会得到一个错误,“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
Complete Trace:完整的跟踪:
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'
This traceback shows clearly what happened:这个回溯清楚地显示了发生了什么:
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'
There is this:有这个:
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
and doing that ends up doing this:这样做最终会这样做:
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
In other words, from api.utils import must_not_be_blank
is executed while api.utils
is already being imported.换句话说,
from api.utils import must_not_be_blank
在api.utils
已经被导入时执行。 At that point, api.utils
is half-done and importing something from it may fail.此时,
api.utils
已完成一半,从中导入某些内容可能会失败。 And it does fail.它确实失败了。
That is called a circular import.这称为循环导入。 You should reorganize the code so that you don't have circular imports, ie if
A
imports B
and B
imports C
, then C
should not import A
or B
.您应该重新组织代码,以便您没有循环导入,即如果
A
导入B
和B
导入C
,那么C
不应导入A
或B
。
It happens very likely due to circular dependency between some modules.这很可能是由于某些模块之间的循环依赖而发生的。 The easiest way to check would be taking look at the dependency graph of the whole project.
最简单的检查方法是查看整个项目的依赖关系图。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.