При объявлении словаря литералом есть ли способ указать, какое значение я ожидаю для определенного ключа?
И затем, для обсуждения: существуют ли руководящие принципы набора текста по словарю в 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]
}
Есть ли лучшая практика для такого рода вещей?
Еще немного фона:
Я работаю с Python в PyCharm и широко использую типизацию, так как это помогает мне прогнозировать и проверять мою работу по мере продвижения. Когда я создаю новые классы, я также иногда добавляю в словарь некоторые редко используемые свойства, чтобы не загромождать объект слишком большим количеством атрибутов (это полезно в режиме отладки).