如何使用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()只要我有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中,我可以这样做:
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语句的项目代码样式。
发布于 2020-02-18 00:25:36
只要您使用的是Python,您就可以“重新注释”变量的类型,可以任意使用相同的语法来“声明”变量的类型,而不需要初始化它( 3.6+ )。
在您提供的示例中,以下代码段具有您预期的行为:
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另外,您还可以通过调用带有禁用断言标志的解释器,在生产环境中保留断言语句和-O。根据同事对Python中的类型暗示的熟悉程度,您的同事可能认为这一点更容易读懂,也可能不认为它更易读。
https://stackoverflow.com/questions/60271719
复制相似问题