当将字典声明为文字时,是否有一种方法可以提示您特定键的值是什么?
然后讨论:在Python中是否有关于字典键入的指导原则?我想知道在字典中混合类型是否被认为是不好的做法。
这是一个例子:
考虑在类的中声明字典__init__:
__init__
(免责声明:我意识到在示例中,某些.elements条目可能更适合作为类属性,但这只是为了示例)。
.elements
class Rectangle: def __init__(self, corners: Tuple[Tuple[float, float]], **kwargs): self.x, self.z = corners[0][0], corners[0][1] self.elements = { 'front': Line(corners[0], corners[1]), 'left': Line(corners[0], corners[2]), 'right': Line(corners[1], corners[3]), 'rear': Line(corners[3], corners[2]), 'cog': calc_cog(corners), 'area': calc_area(corners), 'pins': None } class Line: def __init__(self, p1: Tuple[float, float], p2: Tuple[float, float]): self.p1, self.p2 = p1, p2 self.vertical = p1[0] == p2[0] self.horizontal = p1[1] == p2[1]
当我键入以下内容时
rec1 = Rectangle(rec1_corners, show=True, name='Nr1') rec1.sides['f...
皮查姆会'front' 为我建议。当我做的更好
'front'
rec1.sides['front'].ver...
皮查姆会建议 .vertical
.vertical
因此,Pycharm会记住该类的字典文字声明中的键__init__,以及它们的值的预期类型。或更确切地说:它期望任何值都具有文字声明中的任何一种类型- 可能与我执行过will所做的相同self.elements = {} # type: Union[type1, type2]。无论哪种方式,我都觉得它很有帮助。
self.elements = {} # type: Union[type1, type2]
如果您的函数有类型提示的输出,Pycharm也会考虑到这一点。
因此,假设在Rectangle上面的示例中,我想指出那pins是一个Pin对象列表…如果pins是普通的类属性,则它将是
Rectangle
pins
Pin
self.pins = None # type: List[Pin]
(前提是必要的进口已经完成)
有没有办法在字典文字声明中给出相同的类型提示?
以下内容 无法 实现我想要的功能:
Union[...]在文字声明的末尾添加类型提示?
Union[...]
'area': calc_area(corners), 'pins': None } # type: Union[Line, Tuple[float, float], float, List[Pin]]
在每一行中添加一个类型提示:
'area': calc_area(corners), # type: float 'pins': None # type: List[Pin] }
这种事情是否有最佳实践?
更多背景:
我在PyCharm中使用Python,并且大量使用了打字,因为它可以帮助我预测和验证我的工作。创建新类时,有时还会将一些不常用的属性放入字典中,以避免过多的属性使对象混乱(这在调试模式下很有用)。
您正在寻找TypedDict。目前,它只是一个仅适用于mypy的扩展程序,但是有计划使其在不久的将来成为官方认可的类型。不过,我不确定PyCharm是否支持此功能。
因此,就您而言,您可以:
from mypy_extensions import TypedDict RectangleElements = TypedDict('RectangleElements', { 'front': Line, 'left': Line, 'right': Line, 'rear': Line, 'cog': float, 'area': float, 'pins': Optional[List[Pin]] }) class Rectangle: def __init__(self, corners: Tuple[Tuple[float, float]], **kwargs): self.x, self.z = corners[0][0], corners[0][1] self.elements = { 'front': Line(corners[0], corners[1]), 'left': Line(corners[0], corners[2]), 'right': Line(corners[1], corners[3]), 'rear': Line(corners[3], corners[2]), 'cog': calc_cog(corners), 'area': calc_area(corners), 'pins': None } # type: RectangleElements
如果您使用的是Python 3.6+,则可以使用基于类的语法来更好地键入所有内容。
不过,在您的特定情况下,我认为大多数人只会将这些数据存储为常规字段而不是字典。我确定您已经考虑了该方法的优缺点,所以我将不为您讲解。