使用类型注释来缩小已声明的 Python 变量的类型范围

如何在Python中使用类型注释来更改或缩小已声明变量的类型,以使或其他类型感知系统理解新类型。pycharm


例如,我可能有两个类:


class A:

   is_b = False

   ...


class B(A):

   is_b = True


   def flummox(self):

       return '?'

以及其他地方的另一个功能:


def do_something_to_A(a_in: A):

    ...

    if a_in.is_b:

       assert isinstance(a_in, B)  # THIS IS THE LINE...

       a_in.flummox()

只要我有声明,PyCharm就会明白我已经缩小到B类,而不是抱怨。没有它,将出现诸如之类的错误/警告。asserta_in.flummox()a_in has no method flummox


我的问题是,是否有PEP 484(或后继者)方法来显示(最初可能是A型或B型或其他东西)现在是B型而没有断言语句。该语句还给出了类型错误。a_inb_in : B = a_in


在TypeScript中,我可以做这样的事情:


if a_in.is_b:

   const b_in = <B><any> a_in;

   b_in.flummox()


// or


if a_in.is_b:

   (a_in as B).flummox()

我不想使用断言行有两个主要原因是(1)速度对这部分代码非常重要,并且每次运行该行时都有一个额外的调用会使其速度过慢,以及(2)禁止裸断言语句的项目代码样式。is_instance


鸿蒙传说
浏览 100回答 1
1回答

qq_花开花谢_0

只要您使用的是 Python 3.6+,就可以使用与在不初始化变量的情况下用于“声明”变量类型的相同语法任意地“重新注释”变量的类型(PEP 526)。在您提供的示例中,以下代码段具有您期望的行为:def do_something_to_A(a_in: A):&nbsp; &nbsp; ...&nbsp; &nbsp; if a_in.is_b:&nbsp; &nbsp; &nbsp; &nbsp;a_in: B&nbsp; &nbsp; &nbsp; &nbsp;a_in.flummox()我已经测试了PyCharm 2019.2是否正确检测到了这种技术。值得注意的是,这不会产生运行时成本,因为无论是否添加此注释语句,都会生成相同的字节码。鉴于以下定义,def do_something_with_annotation(a_in: A):&nbsp;&nbsp; &nbsp; &nbsp;if a_in.is_b:&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; a_in: B&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; a_in.flummox()&nbsp;def do_something_without_annotation(a_in: A):&nbsp;&nbsp; &nbsp; &nbsp;if a_in.is_b:&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; a_in.flummox()&nbsp;dis 产生以下字节码:>>> dis.dis(do_something_with_annotation)&nbsp; 3&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0 LOAD_FAST&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 0 (a_in)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2 LOAD_ATTR&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 0 (is_b)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 4 POP_JUMP_IF_FALSE&nbsp; &nbsp; &nbsp; &nbsp;14&nbsp; 5&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;6 LOAD_FAST&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 0 (a_in)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 8 LOAD_ATTR&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1 (flummox)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;10 CALL_FUNCTION&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 0&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;12 POP_TOP&nbsp; &nbsp; &nbsp; &nbsp; >>&nbsp; &nbsp;14 LOAD_CONST&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0 (None)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;16 RETURN_VALUE>>> dis.dis(do_something_without_annotation)&nbsp; 3&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0 LOAD_FAST&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 0 (a_in)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 2 LOAD_ATTR&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 0 (is_b)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 4 POP_JUMP_IF_FALSE&nbsp; &nbsp; &nbsp; &nbsp;14&nbsp; 4&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;6 LOAD_FAST&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 0 (a_in)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 8 LOAD_ATTR&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 1 (flummox)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;10 CALL_FUNCTION&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 0&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;12 POP_TOP&nbsp; &nbsp; &nbsp; &nbsp; >>&nbsp; &nbsp;14 LOAD_CONST&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;0 (None)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;16 RETURN_VALUE作为旁注,您还可以保留断言语句,并通过调用带有标志的解释器在生产环境中禁用断言。您的同事可能会或可能不会认为这更具可读性,具体取决于他们对Python中类型提示的熟悉程度。-O
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python