PyCharm CE 2019.2.3警告我注意一个类,因为我存储数据的list和值数据type。我试图把它简化到本质上:
class Data:
def __init__(self, length, data_type):
assert isinstance(length, int) and length >= 0
assert isinstance(data_type, type) # commenting this line out removes the warning
self._data = [None] * length
self._data_type = data_type
def set_field(self, index, value):
assert isinstance(value, self._data_type) # commenting this line out removes the warning
assert isinstance(index, int)
self._data[index] = value我在索引上得到警告:

意外类型:
(int,类型)
可能的类型:
(int,无)
(片,IterableNone)
检查信息:此检查检测函数调用表达式中的类型错误。由于动态分派和鸭类型,这在有限但有用的情况下是可能的。函数参数的类型可以在docstring或Python3函数注释中指定。
进一步评论意见:
删除两个标记断言中至少一个的
。
当那些断言指的是value时,对
index中是相当令人困惑的添加附加断言或类型提示的文档字符串的
删除警告。
我的问题:,我是不是做错了这种类型的存储和断言?是否有任何理由提出这一警告,如果没有,你认为有一个方便的方法来删除它吗?
发布于 2019-10-13 19:31:21
这里的问题有两个方面:
None PyCharm初始化了列表,将其视为包含Nones的列表。让我们从元类问题开始:
您可以通过检查data_type是否是type (类的默认元类)的实例来检查它是否是类。然后检查value是否是该类的实例。这很好。
然而,PyCharm假设您的data_type是一个type (这是正确的),但是在isinstance(value, self._data_type)之后,它也假设value是一个type (这是不正确的--应该是_data_type类型)。因此,只要将assert isinstance(...)与data_type和value结合使用,PyCharm就无法推断出正确的value类型!
因此,这可能是PyCharm中的Bug或缺失特性,或者是PyCharm用来确定类型的库中的特性。
第二个问题是,通过使用_data初始化None,PyCharm将推断_data的类型为List[None] (包含Nones的列表)。
因此,如果PyCharm为value扣除除Any (可以分配给任何东西)或None (这是列表内容的预期类型)以外的任何其他内容,就会产生警告。
即使:
def set_field(self, index, value):
assert isinstance(value, int) # <-- difference
assert isinstance(index, int)
self._data[index] = value警告会来的。
此时,您有两个选项:
如果您想使用类型提示,可以例如使用:
from typing import List, Optional, TypeVar, Generic, Type
T = TypeVar('T')
class Data(Generic[T]):
_data: List[Optional[T]]
_data_type: Type[T]
def __init__(self, length: int, data_type: Type[T]):
self._data = [None] * length
self._data_type = data_type
def set_field(self, index: int, value: T):
if isinstance(value, self._data_type):
self._data[index] = value
raise TypeError()注意:我已经完全删除了断言。如果参数没有预期的类型或值,TypeError或ValueError将提供更多的信息。然而,在大多数情况下,文档和/或类型提示可以在Python中充分替代assert和TypeError(至少使用IDE或使用mypy)。
https://stackoverflow.com/questions/58315765
复制相似问题