Как стать автором
Обновить

Комментарии 13

Вопрос: Когда стоит использовать именованные кортежи?
Ответ: Тогда, когда они помогают писать чище, читабельнее и делают код более лёгким в сопровождении, ну и ваще я так щитаю.

Достойно КО.

Интересно посмотреть на пример, когда namedtuple сделали код чище по сравнению со словарями.

На счёт чище не уверен, хотя бы это уродство с нарушением конвенции именования методов


In addition to the methods inherited from tuples, named tuples support three additional methods and two attributes. To prevent conflicts with field names, the method and attribute names start with an underscore.

А методы index и count конфликтов не могут создать?


Но вот то, что namedtuple легче чем словарь или экземпляр любого пользовательского класса — это факт.


Named tuple instances do not have per-instance dictionaries, so they are lightweight and require no more memory than regular tuples.

А также с ним удобно возвращать кортежи из функций.

Думаю, что сравнимо. Про __slots__ я не стал уж упоминать, довольно экзотическая штука. А вы часто это используете?

Там, где я работаю, проблемы с недостатком памяти обычно не возникают.
А если есть проблемы с памятью, то решаются с помощью других подходов (например. yield/delete).
Когда заканчивается память или нехватает процессорного времени, то это обозначает, что «что-то вы делаете не правильно».

Вид car.color выглядит гораздо компактнее, чем car['color'].


При опечатке легче найти ошибку. Если вы написали car.coloor, то IDE может вам показать ошибки, с текстовыми ключами car['coloor'] такое может не получится.

В последних версиях pycharm есть автокомплит и инспекция по ключам словаря. Но читабельность, да, у namedtuple выше, плюс иммутабельность

Лично меня тут сильно раздражает необходимость дублирования имени класса (слева от знака присваивания и в качестве первого аргумента namedtuple). На самом-то деле они могут и не совпадать, например, после рефакторинга в Pycharm, если не поставить галочку насчет поиска в строках и комментариях.

Код ниже рабочий:

from collections import namedtuple
Machine = namedtuple('Car', ['a', 'b'])
machine = Machine(1, 2)
print(machine)


Только выводит:

Car(a=1, b=2)


Т.е. хотелось бы интеграции этого механизма прямо в интерпретаторе, а не «сбоку», как сейчас.
Если есть желание использовать type hints, то в 3.6 для этого есть свой синтаксис:

from typing import NamedTuple

class Man(NamedTuple):
    name: str
    age: int
    weight: float

А с 3.6.1 ещё и методы стало можно добавлять без лишних плясок:


class Vector(NamedTuple):
    x: float = 0.0
    y: float = 0.0

    def scale(self, amount: float) -> 'Vector':
        return Vector(self.x * amount, self.y * amount)
А каково преимущество данного метода по сравнению с обычным классом без наследования?

Я не уверен, что правильно понял ваш вопрос.


Если вы о том, какие преимущества у класса, отнаследованного от NamedTuple по сравнению с обычным, то, на мой взгляд, основное преимущество в том, что он immutable. Плюс в качестве бонуса мы получаем __repr__, __eq__ и __hash__.


Т.е., это своеобразный аналог case class из Scala или data class из Kotlin.

Спасибо, как-то прозевал появление этой возможности. Вот еще-бы Pycharm при вызове конструктора такого класса не подсвечивал правильные аргументы как ошибочные… Впрочем, судя по PY-22102, ошибку обещают исправить в 2017.2
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.