当我通过 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 警告......
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
)的第三个参数