在函数中更改 python 对象类型
Change python object type in a function
我的应用程序中有一个功能,如下所示:
def get_firebase_user(session: Session, firebase_user: FirebaseUser) -> users.User | None:
if some_condition:
return user_instance
我有一个具有基本功能的实用程序模块,所以我决定将在模型为 None 时抛出异常的函数放入该模块中。它看起来像:
def throw_none_exception(inst, detail: str) -> None:
"""Throm exception with given detail if instance is None."""
if inst is None:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail=detail,
)
整个问题都在我的 linter 中。如果我们用第一个函数声明模型并用第二个函数引发错误。在这种工作方式下,linter 无法检测模型如何变化,因此代码如下:
user = get_firebase_user(session, firebase_user)
throw_none_exception(user, "Such user doesn't exists")
if user.id == some_random_id:
return 'You are the luckiest person i\'ve ever seen'
它returns我错了
Item "None" of "Optional[User]" has no attribute "id"
这很烦人:) 我怎样才能重新声明这个模型的类型?或者如何设法用另一种方式做到这一点,这样 linter 就不会出错?
这是一种定义 throw_none_exception
的方法,它可以将 inst
转换为 non-Optional 类型:
from typing import TypeVar, Optional
_T = TypeVar("_T")
def throw_none_exception(inst: Optional[_T], detail: str) -> _T:
"""Throw exception with given detail if instance is None."""
if inst is None:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail=detail,
)
return inst
现在如果你这样做:
user = throw_none_exception(
get_firebase_user(session, firebase_user),
"Such user doesn't exists"
)
user
将具有 non-Optional 类型,您应该能够访问 user.id
而不会出现类型检查错误。
这里的问题是如果 user
不是 None
,linter 无法弄清楚 throw_none_exception
只有 returns。你只需要给 linter 一个提示。 assert
是执行此操作的标准方法。
throw_none_exception(user, "Such user doesn't exist")
assert user is not None
if user.id == some_random_id:
...
即使你 运行 Python 使用 -o
标志,所有 assert
语句都将被编译出来,但你的 linter 仍然会得到满足,因为它是静态依赖的可用信息。
我的应用程序中有一个功能,如下所示:
def get_firebase_user(session: Session, firebase_user: FirebaseUser) -> users.User | None:
if some_condition:
return user_instance
我有一个具有基本功能的实用程序模块,所以我决定将在模型为 None 时抛出异常的函数放入该模块中。它看起来像:
def throw_none_exception(inst, detail: str) -> None:
"""Throm exception with given detail if instance is None."""
if inst is None:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail=detail,
)
整个问题都在我的 linter 中。如果我们用第一个函数声明模型并用第二个函数引发错误。在这种工作方式下,linter 无法检测模型如何变化,因此代码如下:
user = get_firebase_user(session, firebase_user)
throw_none_exception(user, "Such user doesn't exists")
if user.id == some_random_id:
return 'You are the luckiest person i\'ve ever seen'
它returns我错了
Item "None" of "Optional[User]" has no attribute "id"
这很烦人:) 我怎样才能重新声明这个模型的类型?或者如何设法用另一种方式做到这一点,这样 linter 就不会出错?
这是一种定义 throw_none_exception
的方法,它可以将 inst
转换为 non-Optional 类型:
from typing import TypeVar, Optional
_T = TypeVar("_T")
def throw_none_exception(inst: Optional[_T], detail: str) -> _T:
"""Throw exception with given detail if instance is None."""
if inst is None:
raise HTTPException(
status_code=status.HTTP_400_BAD_REQUEST,
detail=detail,
)
return inst
现在如果你这样做:
user = throw_none_exception(
get_firebase_user(session, firebase_user),
"Such user doesn't exists"
)
user
将具有 non-Optional 类型,您应该能够访问 user.id
而不会出现类型检查错误。
这里的问题是如果 user
不是 None
,linter 无法弄清楚 throw_none_exception
只有 returns。你只需要给 linter 一个提示。 assert
是执行此操作的标准方法。
throw_none_exception(user, "Such user doesn't exist")
assert user is not None
if user.id == some_random_id:
...
即使你 运行 Python 使用 -o
标志,所有 assert
语句都将被编译出来,但你的 linter 仍然会得到满足,因为它是静态依赖的可用信息。