我正在使用Django / DRF。我想编写经过类型检查的Python。我也想要绒毛。
Django的模型结构包括为每个模型创建一个管理器类,并将管理器类的实例分配给模型的objects
成员。
由于我使用的是类型注释,所以经理类的方法现在还包括对模型的引用。这会导致flake8报告其中一个错误。
这里是一个例子:
class UserManager:
def create_user(email: str) -> User:
... ^^^^ [flake8] F821: undefined name 'User'
class User:
objects = UserManager()
如果我翻转它们,我会得到:
class User:
objects = UserManager()
^^^^^^^^^^^ [flake8] F821: undefined name 'UserManager'
class UserManager:
def create_user(email: str) -> User:
...
人们如何编写带类型的,倾斜的Django代码?
答案 0 :(得分:2)
除键入内容外,请注意:Django的模型不需要,您需要为每个模型都拥有一个明确的管理器! Django在每个模型上使用objects
属性生成一个Manager。您只需要添加定制的ModelManager即可用于特定用途。进入类型...
如果您实际上正在使用该类,我认为应该将UserManager放在User之前。您可以将类型包装在引号中以表示尚未定义的名称,PEP 484 under the "Forward References" section的文档对此进行了介绍。
class UserManager:
def create_user(email: str) -> "User":
...
class User:
objects = UserManager()
另一种选择是在注释中使用Python 2语法定义类型提示,Type hinting in Python 2显示类似的答案。
class UserManager:
def create_user(email: str):
# type: (str) -> User
...
答案 1 :(得分:2)
在Python 3.7中,您可以使用from __future__ import annotations
来解决此问题,这将允许类型注释包含正向引用。与使用字符串注释(如另一个答案所建议的)相比,此方法更可取,以简化代码重构和插入。对于不支持前向引用注释的旧版Python,使用引号只是一种解决方法。在Python 4中(如果不是更早的话),这将是默认行为。