当把字典声明为文字时,有没有一种方法可以提示我对特定键期望什么值?
然后,进行讨论:在Python中有关于字典类型的指导原则吗?我想知道在字典中混合类型是否被认为是不好的做法。
下面是一个例子:
考虑一个类的__init__
中的字典声明:
- (免责声明:我意识到在这个例子中,一些
.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...
Pycharm会为我建议'front'
。更好的是,当我这样做的时候
rec1.sides['front'].ver...
Pycharm会建议.vertical
所以Pycharm记住了类的__init__
中字典文字声明的键,以及它们的值的预期类型。它期望任何值都具有文本声明中的任何一种类型--可能就像我做了一个self.elements = {} # type: Union[type1, type2]
一样。
如果你的函数有它们的输出类型提示,那么Pycharm也会考虑到这一点。
因此,假设在上面的Rectangle
示例中,我想指出pins
是Pin
对象的列表......如果pins
是一个普通类属性,它将是:
self.pins = None # type: List[Pin]
(前提是已完成必要的导入)
有没有办法在字典文字声明中给予相同的类型提示?
以下内容无法实现我的期望:
是否在文本声明的末尾添加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,并且我广泛使用类型化,因为它帮助我预测和验证我的工作。当我创建新的类时,我有时也会把一些不常用的属性放入字典中,以避免过多的属性使对象变得混乱(这在调试模式中很有帮助)。
3条答案
按热度按时间jjhzyzn01#
你正在寻找TypedDict。它目前只是一个mypy专用的扩展,但是在不久的将来有计划扩展到make it an officially sanctioned type。我不确定PyCharm是否支持这个特性。
所以,在你的情况下,你会做:
如果你使用的是Python 3.6+,你可以使用基于类的语法更优雅地输入。
不过,在您的具体情况下,我想大多数人会将这些数据片段存储为常规字段,而不是dicture。我相信您已经考虑过这种方法的利弊,所以我就不对您进行说教了。
7uzetpgm2#
最简单的方法:
打字字典-PEP 589
rsl1atfo3#
经过更多的研究,到目前为止我能找到的最好的解决方法是确保类
Pin
可以返回某种占位符,然后在文本声明中使用占位符作为值。因此:
现在,在OP中的示例中,我可以执行以下操作来实现我想要的:
然而,如果我有一个基本类型(或类型)作为条目,这将不起作用。
其中
color
需要一个字符串,lap_times
需要一个带有浮点数的列表...在这种情况下,最好的解决方法是
这两个似乎都不是很优雅,所以我仍然希望有人能建议更好的东西。