为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

鸿蒙传说 2022-08-02 15:43:18
如何在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()// orif a_in.is_b:   (a_in as B).flummox()我不想使用断言行有两个主要原因是(1)速度对这部分代码非常重要,并且每次运行该行时都有一个额外的调用会使其速度过慢,以及(2)禁止裸断言语句的项目代码样式。is_instance
查看完整描述

1 回答

?
qq_花开花谢_0

TA贡献1835条经验 获得超7个赞

只要您使用的是 Python 3.6+,就可以使用与在不初始化变量的情况下用于“声明”变量类型的相同语法任意地“重新注释”变量的类型(PEP 526)。


在您提供的示例中,以下代码段具有您期望的行为:


def do_something_to_A(a_in: A):

    ...

    if a_in.is_b:

       a_in: B

       a_in.flummox()


我已经测试了PyCharm 2019.2是否正确检测到了这种技术。


值得注意的是,这不会产生运行时成本,因为无论是否添加此注释语句,都会生成相同的字节码。鉴于以下定义,


def do_something_with_annotation(a_in: A): 

     if a_in.is_b: 

        a_in: B 

        a_in.flummox() 



def do_something_without_annotation(a_in: A): 

     if a_in.is_b: 

        a_in.flummox() 

dis 产生以下字节码:


>>> dis.dis(do_something_with_annotation)

  3           0 LOAD_FAST                0 (a_in)

              2 LOAD_ATTR                0 (is_b)

              4 POP_JUMP_IF_FALSE       14


  5           6 LOAD_FAST                0 (a_in)

              8 LOAD_ATTR                1 (flummox)

             10 CALL_FUNCTION            0

             12 POP_TOP

        >>   14 LOAD_CONST               0 (None)

             16 RETURN_VALUE

>>> dis.dis(do_something_without_annotation)

  3           0 LOAD_FAST                0 (a_in)

              2 LOAD_ATTR                0 (is_b)

              4 POP_JUMP_IF_FALSE       14


  4           6 LOAD_FAST                0 (a_in)

              8 LOAD_ATTR                1 (flummox)

             10 CALL_FUNCTION            0

             12 POP_TOP

        >>   14 LOAD_CONST               0 (None)

             16 RETURN_VALUE

作为旁注,您还可以保留断言语句,并通过调用带有标志的解释器在生产环境中禁用断言。您的同事可能会或可能不会认为这更具可读性,具体取决于他们对Python中类型提示的熟悉程度。-O


查看完整回答
反对 回复 2022-08-02
  • 1 回答
  • 0 关注
  • 99 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号