【问题标题】:Python type hints with imported class methods带有导入类方法的 Python 类型提示
【发布时间】:2020-11-23 19:47:07
【问题描述】:

为了将一个大类拆分成多个文件,this answer 建议在class 级别使用import 命令来加载定义可以移动到其他模块的方法。作为一个最小的例子,

class_def.py:

class C:
    from _methods import m

_methods.py:

def m(self):
    return "hello"

通常,大多数具有代码完成功能的 IDE 会将在某些类中定义的函数识别为绑定方法,并且self 将自动被识别为具有定义该方法的类的类型。不幸的是,在上述情况下,我没有在类中定义m。仅看_methods.py 是不可能判断self 应该具有C 类型的。

m 的定义中,如果我插入以self. 开头的行,我的IDE 无法建议m 或我可能在C 中实现的任何其他方法。

显而易见的解决方案是添加类型提示:

from class_def import C

def m(self: C):
    return "hello"

但是现在我们有一个循环导入:C 的定义导入了_methods,但是_methods 导入了C。如何在不引入循环导入的情况下创建类型提示?

我目前使用的是 Python 3.7,但我也对需要更高版本的解决方案感兴趣。

【问题讨论】:

  • 如果一个类变得那么大,你必须拆分它,那么你的设计中的某些东西很有可能是次优的。我建议花一些时间进行重构。
  • 我发现很难想象有比这更理想的方式来重构一个代表应该具有大量功能的对象的大型类。但这可能是我的无知(我不是程序员)。
  • 这能回答你的问题吗? Python type hinting without cyclic imports
  • @Georgy,差不多。我认为下面的答案回答了这个问题。

标签: python python-3.7 type-hinting python-typing


【解决方案1】:
  1. 修复循环导入,仅在类型检查期间使用typing.TYPE_CHECKING 标志导入C

  2. 这会使C 的值在运行时未定义。将其括在引号中 ("C") 或导入 __future__.annotations:

_methods.py 变体 1:

from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from class_def import C

def m(self: "C"):
    return "hello"

_methods.py 变体 2:

from __future__ import annotations
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from class_def import C

def m(self: C):
    return "hello"

【讨论】:

    猜你喜欢
    • 2021-09-13
    • 2021-10-20
    • 2017-02-06
    • 2019-04-12
    • 2018-02-17
    • 2017-10-09
    • 2017-10-14
    • 2017-11-01
    相关资源
    最近更新 更多