Pycharm 中动态生成类的类型提示

问题描述 投票:0回答:1

当我通过 Python

type( )
函数使用动态创建的类时,我试图让 Pycharm 的 linter 停止抱怨。实际代码的简化版本如下所示。

是的,像这样使用类对象很奇怪,但在真正的代码中,这是有意义的(SQLAlchemy ORM 类,如果你好奇的话)。请注意指出 Pycharm 警告的最后一行。

class MyClass(object):
    ID_NUM: int = 0

    def __init__(self, id_num: int, first_name: str, last_name: str):
        self.ID_NUM = id_num
        self.first_name = first_name
        self.last_name = last_name


def make_augmented_class(cls):
    def augmented__eq__(self, other):
        try:
            return self.id_num == other.id_num
        except AttributeError:
            return False

    new_cls = type('{}Augmented'.format(cls.__name__), tuple([cls]), {})
    new_cls.__eq__ = augmented__eq__
    return new_cls


def do_stuff(my_class):
    print(my_class.ID_NUM)


if __name__ == '__main__':
    do_stuff(MyClass)

    augmented_class = make_augmented_class(MyClass)
    do_stuff(augmented_class)  # <=== PYCHARM CODE LINTER COMPLAINS THAT "Type 'type' doesn't have expected attribute 'ID_NUM'"

我已经为

do_stuff( )
函数尝试了几种类型提示,例如
def do_stuff(my_class: type):
def do_stuff(my_class: MyClass):
,但这只会导致不同的 linter 警告。

代码可以工作,但我想以某种方式消除 linter 警告......

python types dynamic sqlalchemy pycharm
1个回答
0
投票

PyCharm 不太能够处理动态构造的类(这是可以理解的,这样的动态系统很难或不可能分析)。

但是,您可以注释

make_augmented_class
来消除此警告,并使用小
cast
来告诉 PyCharm 信任您:

def make_augmented_class(cls: type[T]) -> type[T]:
    def augmented__eq__(self, other):
        try:
            return self.id_num == other.id_num
        except AttributeError:
            return False

    new_cls = type('{}Augmented'.format(cls.__name__), tuple([cls]), {})
    new_cls.__eq__ = augmented__eq__
    return cast(type[T], new_cls)

(有趣的是,mypy 抱怨对

__eq__
的分配,而 PyCharm 则不然。但是,我相信 mypy 在这里是错误的,因此用
type: ignore
静音该行是正确的操作过程。或者您可以将其移至
type
)的第三个参数

© www.soinside.com 2019 - 2024. All rights reserved.