首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用类型注释缩小已经声明的Python变量的类型

使用类型注释缩小已经声明的Python变量的类型
EN

Stack Overflow用户
提问于 2020-02-17 23:21:54
回答 1查看 156关注 0票数 1

如何使用Python中的类型注释来更改或缩小已经声明的变量的类型,从而使pycharm或其他类型识别系统理解新类型。

例如,我可能有两个类:

代码语言:javascript
复制
class A:
   is_b = False
   ...

class B(A):
   is_b = True

   def flummox(self):
       return '?'

以及其他地方的另一项职能:

代码语言:javascript
复制
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()

只要我有assert语句,PyCharm就会明白,我已经将a_in缩小为B类,而不是抱怨.flummox()。没有它,就会出现错误/警告,比如a_in has no method flummox

我的问题是,是否有一种PEP 484 (或后继)方法来表明a_in (可能是A或B类型或其他类型的)现在是B类型的,而没有assert语句。b_in : B = a_in语句还会给出类型错误。

在TypeScript中,我可以这样做:

代码语言:javascript
复制
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)速度对代码的这一部分非常重要,每次运行该行时都有一个额外的is_instance调用会减慢它的速度;(2)禁止只使用assert语句的项目代码样式。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-02-18 00:25:36

只要您使用的是Python,您就可以“重新注释”变量的类型,可以任意使用相同的语法来“声明”变量的类型,而不需要初始化它( 3.6+ )。

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

代码语言:javascript
复制
def do_something_to_A(a_in: A):
    ...
    if a_in.is_b:
       a_in: B
       a_in.flummox()

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

值得注意的是,这不需要运行时成本,因为使用或不使用添加的注释语句生成相同的字节码。考虑到以下定义,

代码语言:javascript
复制
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生成以下字节码:

代码语言:javascript
复制
>>> 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

另外,您还可以通过调用带有禁用断言标志的解释器,在生产环境中保留断言语句和-O。根据同事对Python中的类型暗示的熟悉程度,您的同事可能认为这一点更容易读懂,也可能不认为它更易读。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60271719

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档