【问题标题】:How do you type hint an additional attribute on an object?如何键入提示对象的附加属性?
【发布时间】:2020-12-12 02:35:16
【问题描述】:

我有一个自定义测试运行程序,它使用检查来查找以test_ 开头的所有函数。有一次,我向函数对象添加了一个属性。这样做是为了让测试运行者稍后可以访问文档字符串信息。

我真的很想为函数列表创建一个类型提示,以便我的 IDE (pycharm) 知道 tdi 确实是函数对象的一个​​属性。

如何构建这样的类型提示?

for m, fn in module.__dict__.items():
        if m.startswith(prefix):
            if callable(fn):
                tdi = getTestDocInfo(fn) # reads the docstring for tags and puts the info in a dataclass
                fn.tdi = tdi
                tests.append(fn)

编辑: 在这种情况下,类型提示应该传达对象是一个函数并且它具有属性tdi

正如@chepner 指出的那样,这里需要 Protocol 类型提示的构建块。

这是有效的。

@runtime_checkable
class TestFunc(Protocol):
    tdi: TestDocInfo
    def __call__(self, testresult: TestResult, shareditems: SharedItems): pass

tests: List[TestFunc]. #type hint I am looking for.

【问题讨论】:

标签: python python-3.x type-hinting


【解决方案1】:

这似乎是 typing.Protocoltyping.runtime_checkable 的工作:

from typing import Protocol, runtime_checkable

@runtime_checkable
class HasTDI(Protocol):
    tdi: int  # Or whatever type is appropriate.

然后

isinstance(fn, HasTDI)

如果fn.tdi 存在并且是int,则应该为真。

不过,恐怕我不知道 PyCharm 是否会利用这些信息。

【讨论】:

  • 这真的很有用。虽然我可能不得不修改我的问题。我很好奇是否还能保留“FunctionType”或“Callable”的类型提示。
  • 哦,笨蛋,List[Union[types.FunctionType, HasTDI]] 就像一个魅力!
  • Union 暗示一个项目可以是一个没有tdii 属性的函数,或者不是一个函数(或一般可调用)。也许您也希望将HasTDI 子类化为FunctionType?例如,class HasTDI(Protocol, FunctionType) 或类似的东西,然后是 List[HasTDI]
  • 你是对的。后来我玩了一下,发现工会不太对劲。我最终只是将def __call__(self, testresult: TestResult, shareditems: SharedItems): pass 添加到HasTDI,然后只使用List[HasTDI]。再次感谢Protocol 的提醒
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-07-31
  • 2012-05-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-01
  • 2011-10-03
  • 1970-01-01
相关资源
最近更新 更多