我的环境的快速描述:
- django 4.2.11
- mypy 1.9.0
- django-stubs 4.2.5
这是我在下面制作的综合示例,仅供该帖子使用,请不要根据名称的含义等来判断我。重点是如何处理 mypy 错误...
我有两个模型,一个通过ForeignKey引用另一个模型:
class Author(models.Model):
name = models.CharField()
class Book(models.Model):
author = models.ForeignKey(Author, blank=False, null=True, ...)
然后我有一组类似的函数,对于每个函数都有一个规则:我们检查,该作者不是 None,如果是 - 则引发错误:ImproperlyConfigured:
def _check_configuration(book: Book) -> None:
if not book.author:
raise ImproperlyConfigured()
def func1(book: Book) -> int:
_check_configuration(book)
....
author_name = book.author.name # here it comes...
def func2(book: Book) -> str:
_check_configuration(book)
....
出于 DRY 目的,我使用验证功能。如果我将
if book.author is None...
直接放入 func1 - 那么错误就会消失。
这是错误:
error: ... "Author | None" has no attribute "name" [union-attr]
如何向mypy解释作者肯定不是None?
谢谢!
ChatGPT 和谷歌搜索。 ChatGPT 返回关于该问题的愚蠢建议,对于 Google,我什至无法制定请求,我尝试过的一切 - 引导我解决另一个问题...
对于像这样简单的检查,我将使用断言 - 您可以使用自定义错误,类型检查器可以推断键入信息,并且重复的行几乎不再存在(我使用下面的数据类来呈现示例) ,但它适用于任何东西):
from dataclasses import dataclass
@dataclass
class Author:
name: str
@dataclass
class Book:
author: Author | None
class ImproperlyConfigured(ValueError):
pass
def func1(book: Book) -> str:
assert book.author, ImproperlyConfigured
author_name = book.author.name
return author_name
func1(Book(None))