Что такое "именованные кортежи" в Python?

Читая изменения в Python 3.1, я обнаружил кое-что... неожиданное:

Кортеж sys.version_info теперь является именованным кортежем:

Я никогда раньше не слышал об именованных кортежах и думал, что элементы могут быть проиндексированы либо по номерам (как в кортежах и списках), либо по ключам (как в диктах). Я никогда не ожидал, что они могут быть проиндексированы в обоих направлениях.

Итак, мои вопросы:

  • Как называются кортежи?
  • Как их использовать?
  • Почему / когда я должен использовать именованные кортежи вместо обычных кортежей?
  • Почему / когда я должен использовать нормальные кортежи вместо именованных кортежей?
  • Есть ли какой-либо "именованный список" (изменяемая версия именованного кортежа)?

13 ответов

Решение

Именованные кортежи - это, в основном, простые в создании, легкие типы объектов. На именованные экземпляры кортежей можно ссылаться, используя объектную переменную разыменования или стандартный синтаксис кортежей. Их можно использовать аналогично struct или другие распространенные типы записей, за исключением того, что они являются неизменяемыми. Они были добавлены в Python 2.6 и Python 3.0, хотя есть рецепт для реализации в Python 2.4.

Например, обычно представлять точку в виде кортежа (x, y), Это приводит к коду, подобному следующему:

pt1 = (1.0, 5.0)
pt2 = (2.5, 1.5)

from math import sqrt
line_length = sqrt((pt1[0]-pt2[0])**2 + (pt1[1]-pt2[1])**2)

Используя именованный кортеж, он становится более читабельным:

from collections import namedtuple
Point = namedtuple('Point', 'x y')
pt1 = Point(1.0, 5.0)
pt2 = Point(2.5, 1.5)

from math import sqrt
line_length = sqrt((pt1.x-pt2.x)**2 + (pt1.y-pt2.y)**2)

Однако именованные кортежи по-прежнему обратно совместимы с обычными кортежами, поэтому следующее будет работать:

Point = namedtuple('Point', 'x y')
pt1 = Point(1.0, 5.0)
pt2 = Point(2.5, 1.5)

from math import sqrt
# use index referencing
line_length = sqrt((pt1[0]-pt2[0])**2 + (pt1[1]-pt2[1])**2)
 # use tuple unpacking
x1, y1 = pt1

Таким образом, вы должны использовать именованные кортежи вместо кортежей везде, где вы думаете, что объектная нотация сделает ваш код более понятным и более легким для чтения. Я лично начал использовать их для представления очень простых типов значений, особенно при передаче их в качестве параметров функциям. Это делает функции более читаемыми, не видя контекста упаковки кортежей.

Кроме того, вы также можете заменить обычные неизменяемые классы, которые не имеют функций, только поля с ними. Вы даже можете использовать ваши именованные типы кортежей в качестве базовых классов:

class Point(namedtuple('Point', 'x y')):
    [...]

Однако, как и в случае кортежей, атрибуты в именованных кортежах неизменны:

>>> Point = namedtuple('Point', 'x y')
>>> pt1 = Point(1.0, 5.0)
>>> pt1.x = 2.0
AttributeError: can't set attribute

Если вы хотите изменить значения, вам нужен другой тип. Существует удобный рецепт для изменяемых типов записей, которые позволяют вам устанавливать новые значения для атрибутов.

>>> from rcdtype import *
>>> Point = recordtype('Point', 'x y')
>>> pt1 = Point(1.0, 5.0)
>>> pt1 = Point(1.0, 5.0)
>>> pt1.x = 2.0
>>> print(pt1[0])
    2.0

Я не знаю ни о какой форме "именованного списка", которая позволяет вам добавлять новые поля. Вы можете просто использовать словарь в этой ситуации. Именованные кортежи могут быть преобразованы в словари с помощью pt1._asdict() который возвращается {'x': 1.0, 'y': 5.0} и может работать со всеми обычными функциями словаря.

Как уже отмечалось, вы должны проверить документацию для получения дополнительной информации, из которой были построены эти примеры.

Как называются кортежи?

Именованный кортеж - это кортеж.

Он делает все, что может кортеж.

Но это больше, чем просто кортеж.

Это определенный подкласс кортежа, который программно создается по вашей спецификации с именованными полями и фиксированной длиной.

Это, например, создает подкласс кортежа, и, кроме того, что он имеет фиксированную длину (в данном случае три), он может использоваться везде, где кортеж используется без разрывов. Это называется заменяемостью по Лискову:

>>> from collections import namedtuple
>>> class_name = 'ANamedTuple'
>>> fields = 'foo bar baz'
>>> ANamedTuple = namedtuple(class_name, fields)

Это создает его экземпляр:

>>> ant = ANamedTuple(1, 'bar', [])

Мы можем проверить его и использовать его атрибуты:

>>> ant
ANamedTuple(foo=1, bar='bar', baz=[])
>>> ant.foo
1
>>> ant.bar
'bar'
>>> ant.baz.append('anything')
>>> ant.baz
['anything']

Более глубокое объяснение

Чтобы понять именованные кортежи, сначала нужно узнать, что такое кортеж. Кортеж - это, по сути, неизменный (не может быть изменен в памяти) список.

Вот как вы можете использовать обычный кортеж:

>>> student_tuple = 'Lisa', 'Simpson', 'A'
>>> student_tuple
('Lisa', 'Simpson', 'A')
>>> student_tuple[0]
'Lisa'
>>> student_tuple[1]
'Simpson'
>>> student_tuple[2]
'A'

Вы можете расширить кортеж с повторяемой распаковкой:

>>> first, last, grade = student_tuple
>>> first
'Lisa'
>>> last
'Simpson'
>>> grade
'A'

Именованные кортежи - это кортежи, которые позволяют обращаться к их элементам по имени, а не только по индексу!

Вы делаете именованный кортеж так:

>>> from collections import namedtuple
>>> Student = namedtuple('Student', ['first', 'last', 'grade'])

Вы также можете использовать одну строку с именами, разделенными пробелами, чуть более удобочитаемое использование API:

>>> Student = namedtuple('Student', 'first last grade')

Как их использовать?

Вы можете делать все, что могут делать кортежи (см. Выше), а также делать следующее:

>>> named_student_tuple = Student('Lisa', 'Simpson', 'A')
>>> named_student_tuple.first
'Lisa'
>>> named_student_tuple.last
'Simpson'
>>> named_student_tuple.grade
'A'
>>> named_student_tuple._asdict()
OrderedDict([('first', 'Lisa'), ('last', 'Simpson'), ('grade', 'A')])
>>> vars(named_student_tuple)
OrderedDict([('first', 'Lisa'), ('last', 'Simpson'), ('grade', 'A')])
>>> new_named_student_tuple = named_student_tuple._replace(first='Bart', grade='C')
>>> new_named_student_tuple
Student(first='Bart', last='Simpson', grade='C')

Комментатор спросил:

В большом скрипте или программе, где обычно определяется именованный кортеж?

Типы, которые вы создаете с namedtuple В основном это классы, которые вы можете создавать с легким сокращением. Относитесь к ним как к классам. Определите их на уровне модуля, чтобы маринованные и другие пользователи могли их найти.

Рабочий пример на уровне глобального модуля:

>>> from collections import namedtuple
>>> NT = namedtuple('NT', 'foo bar')
>>> nt = NT('foo', 'bar')
>>> import pickle
>>> pickle.loads(pickle.dumps(nt))
NT(foo='foo', bar='bar')

И это демонстрирует неспособность найти определение:

>>> def foo():
...     LocalNT = namedtuple('LocalNT', 'foo bar')
...     return LocalNT('foo', 'bar')
... 
>>> pickle.loads(pickle.dumps(foo()))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
_pickle.PicklingError: Can't pickle <class '__main__.LocalNT'>: attribute lookup LocalNT on __main__ failed

Почему / когда я должен использовать именованные кортежи вместо обычных кортежей?

Используйте их, когда это улучшит ваш код, чтобы семантика элементов кортежа была выражена в вашем коде. Вы можете использовать их вместо объекта, если вы иначе использовали бы объект с неизменными атрибутами данных и без функциональности. Вы также можете разделить их на подклассы для добавления функциональности, например:

class Point(namedtuple('Point', 'x y')):
    """adding functionality to a named tuple"""
        __slots__ = ()
        @property
        def hypot(self):
            return (self.x ** 2 + self.y ** 2) ** 0.5
        def __str__(self):
            return 'Point: x=%6.3f  y=%6.3f  hypot=%6.3f' % (self.x, self.y, self.hypot)

Почему / когда я должен использовать нормальные кортежи вместо именованных кортежей?

Вероятно, было бы регрессией перейти от использования именованных кортежей к кортежам. Первоначальное решение по проектированию сосредотачивается на том, стоит ли затраты на дополнительный код, улучшающие читаемость при использовании кортежа.

Нет никакой дополнительной памяти, используемой именованными кортежами против кортежей.

Есть ли какой-либо "именованный список" (изменяемая версия именованного кортежа)?

Вы ищете либо объект с прорезями, который реализует все функциональные возможности списка статического размера, либо подклассовый список, который работает как именованный кортеж (и который каким-то образом блокирует изменение размера списка).

А теперь расширенный и, возможно, даже подменный Лисков, пример первого:

from collections import Sequence

class MutableTuple(Sequence): 
    """Abstract Base Class for objects that work like mutable
    namedtuples. Subclass and define your named fields with 
    __slots__ and away you go.
    """
    __slots__ = ()
    def __init__(self, *args):
        for slot, arg in zip(self.__slots__, args):
            setattr(self, slot, arg)
    def __repr__(self):
        return type(self).__name__ + repr(tuple(self))
    # more direct __iter__ than Sequence's
    def __iter__(self): 
        for name in self.__slots__:
            yield getattr(self, name)
    # Sequence requires __getitem__ & __len__:
    def __getitem__(self, index):
        return getattr(self, self.__slots__[index])
    def __len__(self):
        return len(self.__slots__)

И использовать, просто подкласс и определить __slots__:

class Student(MutableTuple):
    __slots__ = 'first', 'last', 'grade' # customize 


>>> student = Student('Lisa', 'Simpson', 'A')
>>> student
Student('Lisa', 'Simpson', 'A')
>>> first, last, grade = student
>>> first
'Lisa'
>>> last
'Simpson'
>>> grade
'A'
>>> student[0]
'Lisa'
>>> student[2]
'A'
>>> len(student)
3
>>> 'Lisa' in student
True
>>> 'Bart' in student
False
>>> student.first = 'Bart'
>>> for i in student: print(i)
... 
Bart
Simpson
A

namedtuple - это фабричная функция для создания класса кортежей. С помощью этого класса мы можем создавать кортежи, которые также могут вызываться по имени.

import collections

#Create a namedtuple class with names "a" "b" "c"
Row = collections.namedtuple("Row", ["a", "b", "c"], verbose=False, rename=False)   

row = Row(a=1,b=2,c=3) #Make a namedtuple from the Row class we created

print row    #Prints: Row(a=1, b=2, c=3)
print row.a  #Prints: 1
print row[0] #Prints: 1

row = Row._make([2, 3, 4]) #Make a namedtuple from a list of values

print row   #Prints: Row(a=2, b=3, c=4)

namedtuples - отличная функция, они являются идеальным контейнером для данных. Когда вам нужно "хранить" данные, вы должны использовать кортежи или словари, например:

user = dict(name="John", age=20)

или же:

user = ("John", 20)

Подход словаря является подавляющим, так как dict изменчив и медленнее, чем кортежи. С другой стороны, кортежи являются неизменяемыми и легковесными, но им не хватает читабельности для большого количества записей в полях данных.

Именованные кортежи являются идеальным компромиссом для двух подходов, они имеют отличную читабельность, легкость и неизменность (плюс они полиморфны!).

Именованные кортежи обеспечивают обратную совместимость с кодом, который проверяет версию, подобную этой

>>> sys.version_info[0:2]
(3, 1)

позволяя будущему коду быть более явным с помощью этого синтаксиса

>>> sys.version_info.major
3
>>> sys.version_info.minor
1

namedtuple

это один из самых простых способов очистить ваш код и сделать его более читабельным. Он самодокументирует, что происходит в кортеже. Экземпляры именных кортежей так же эффективны в плане памяти, как и обычные кортежи, поскольку у них нет словарей для каждого экземпляра, что делает их быстрее, чем словари.

from collections import namedtuple

Color = namedtuple('Color', ['hue', 'saturation', 'luminosity'])

 p = Color(170, 0.1, 0.6)
 if p.saturation >= 0.5:
     print "Whew, that is bright!"
 if p.luminosity >= 0.5:
     print "Wow, that is light"

Не называя каждый элемент в кортеже, он будет выглядеть так:

p = (170, 0.1, 0.6)
if p[1] >= 0.5:
    print "Whew, that is bright!"
if p[2]>= 0.5:
   print "Wow, that is light"

Намного сложнее понять, что происходит в первом примере. С именованным кортежем каждое поле имеет имя. И вы получаете доступ к нему по имени, а не по позиции или индексу. Вместо p[1] мы можем назвать это p.saturation. Это легче понять. И это выглядит чище.

Создать экземпляр именованного кортежа проще, чем создать словарь.

# dictionary
>>>p = dict(hue = 170, saturation = 0.1, luminosity = 0.6)
>>>p['hue']
170

#nametuple
>>>from collections import namedtuple
>>>Color = namedtuple('Color', ['hue', 'saturation', 'luminosity'])
>>>p = Color(170, 0.1, 0.6)
>>>p.hue
170

Когда вы можете использовать namedtuple

  1. Как уже говорилось, namedtup значительно упрощает понимание кортежей. Так что если вам нужно сослаться на элементы в кортеже, то создание их как именованных кортежей имеет смысл.
  2. Помимо того, что namedtuple более легкий, чем словарь, он также сохраняет порядок в отличие от словаря.
  3. Как и в приведенном выше примере, создать экземпляр namedtuple проще, чем словарь. И ссылка на элемент в именованном кортеже выглядит чище, чем в словаре. p.hue скорее, чем p['hue'],

Синтаксис

collections.namedtuple(typename, field_names[, verbose=False][, rename=False])
  • namedtuple находится в библиотеке коллекций.
  • typename: это имя нового подкласса кортежа.
  • field_names: последовательность имен для каждого поля. Это может быть последовательность, как в списке ['x', 'y', 'z'] или строка x y z (без запятых, просто пробел) или x, y, z,
  • переименовать: если переименовать True неверные имена полей автоматически заменяются позиционными именами. Например, ['abc', 'def', 'ghi','abc'] преобразуется в ['abc', '_1', 'ghi', '_3'], исключая ключевое слово 'def' (поскольку это зарезервированное слово для определения функций) и дубликат имени поля 'abc',
  • подробный: если многословный True определение класса печатается непосредственно перед сборкой.

Вы можете получить доступ к именованным кортежам по их позиции, если вы того пожелаете. p[1] == p.saturation, Он все еще распаковывается как обычный кортеж.

методы

Все обычные методы кортежа поддерживаются. Пример: min(), max(), len(), in, not in, конкатенация (+), index, slice и т. Д. И есть несколько дополнительных для namedtuple. Примечание: все они начинаются с подчеркивания. _replace, _make, _asdict,

_replace Возвращает новый экземпляр именованного кортежа, заменяя указанные поля новыми значениями.

Синтаксис

somenamedtuple._replace(kwargs)

пример

>>>from collections import namedtuple

>>>Color = namedtuple('Color', ['hue', 'saturation', 'luminosity'])
>>>p = Color(170, 0.1, 0.6)

>>>p._replace(hue=87)
Color(87, 0.1, 0.6)

>>>p._replace(hue=87, saturation=0.2)
Color(87, 0.2, 0.6)

Примечание: имена полей не в кавычках; они являются ключевыми словами здесь. Помните: кортежи являются неизменяемыми - даже если они являются именованными кортежами и имеют _replace метод. _replace производит new пример; он не изменяет оригинал и не заменяет старое значение. Конечно, вы можете сохранить новый результат в переменной. p = p._replace(hue=169)

_make

Делает новый экземпляр из существующей последовательности или повторяемой.

Синтаксис

somenamedtuple._make(iterable)

пример

 >>>data = (170, 0.1, 0.6)
 >>>Color._make(data)
Color(hue=170, saturation=0.1, luminosity=0.6)

>>>Color._make([170, 0.1, 0.6])  #the list is an iterable
Color(hue=170, saturation=0.1, luminosity=0.6)

>>>Color._make((170, 0.1, 0.6))  #the tuple is an iterable
Color(hue=170, saturation=0.1, luminosity=0.6)

>>>Color._make(170, 0.1, 0.6) 
Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "<string>", line 15, in _make
TypeError: 'float' object is not callable

Что случилось с последним? Элемент внутри скобки должен быть повторяемым. Таким образом, список или кортеж внутри круглых скобок работает, но последовательность значений без включения в качестве итерируемого возвращает ошибку.

_asdict

Возвращает новый OrderedDict, который сопоставляет имена полей с их соответствующими значениями.

Синтаксис

somenamedtuple._asdict()

пример

 >>>p._asdict()
OrderedDict([('hue', 169), ('saturation', 0.1), ('luminosity', 0.6)])

Ссылка: https://www.reddit.com/r/Python/comments/38ee9d/intro_to_namedtuple/

Также есть именованный список, который похож на именованный кортеж, но изменяемый https://pypi.python.org/pypi/namedlist

  • Они создают подкласс кортежа и добавляют слой для присвоения имен свойств позиционным элементам.

  • Находится в модуле стандартной библиотеки коллекций

              from collections import namedtuple
    

«namedtuple» - это функция, которая генерирует новый класс, наследующий от «кортежа», но также предоставляет «именованные свойства» для доступа к элементам кортежа.

Создание именованных классов кортежей

"namedtuple" - это фабрика классов. Для создания класса требуется несколько вещей.

  • имя класса, которое мы хотим использовать

  • Последовательность имен полей, которые мы хотим назначить, в порядке элементов в кортеже. Имена полей могут быть любыми допустимыми именами переменных, за исключением того, что они не могут начинаться с символа подчеркивания.

  • Возвращаемое значение вызова «namedtuple» будет классом. Нам нужно назначить этот класс имени переменной в нашем коде, чтобы мы могли использовать его для создания экземпляров. Обычно мы используем то же имя, что и имя созданного класса.

    Coords = namedtuple('Coords', ['x', 'y']).

  • Теперь мы можем создавать экземпляры Coords:

            pt=Coords(10,20)
    
  • Есть много способов предоставить список имен полей функции namedtuple.

    • список строк

                   namedtuple('Coords',['x','y'])
      
    • кортеж строк

                   namedtuple('Coords',('x','y'))
      
    • одна строка с именами полей, разделенными пробелами или запятыми

                   namedtuple('Coords','x, y'])
      

Создание именованных кортежей

После того, как мы создали именованный класс кортежа, мы можем создать его экземпляр, как обычный класс. Фактически __new__ метод сгенерированного класса использует имена полей, которые мы предоставили в качестве имен параметров.

      Coords = namedtuple('Coords', ['x', 'y'])
coord=Coords(10,20) 

Доступ к данным в названном кортеже:

Поскольку именованные кортежи - это просто кортежи, мы можем обрабатывать их так же, как и любой другой кортеж: по индексу, нарезке, итерации

      Coords = namedtuple('Coords', ['x', 'y'])
coord=Coords(10,20)       isinstance(coord,tuple) --> True # namedtuple is subclass of tuple

x,y=coord  # Unpacking
x=coord[0] # by index
for e in coord:
    print(e)
  • Теперь мы также можем получить доступ к данным, используя имена полей, которые мы сделали с классами.

               coord.x --> 10
       coord.y --> 20
    
  • Поскольку namedtuple - это сгенерированные классы, наследуемые от кортежа, мы можем написать так:

             class Coord(tuple):
          ....
    
  • "Coord" - это кортеж, поэтому неизменяемый

ключевое слово "переименовать" аргумент для namedtuple

Имена полей не могут начинаться с подчеркивания

        Coords = namedtuple('Coords', ['x', '_y']) # does not work

namedtuple имеет аргумент, состоящий только из ключевых слов, rename (по умолчанию False), который автоматически переименует любое недопустимое имя поля.

      Coords = namedtuple('Coords', ['x', '_y'], rename=True)

имя поля "x" не изменится, но "_y" изменится на _1. 1 - это индекс имени поля.

Самоанализ

Мы можем легко узнать, сгенерированы ли имена полей в именованном кортеже.

           Coords = namedtuple('Coords', ['x', '_y'])
     Coords._fields -> ("x","_1")  # returns tuple

Мы действительно можем увидеть, что такое код для этого класса, используя свойство класса _sourceесли вы используете Python менее 3–3,7. Поскольку могли возникнуть некоторые опасения по поводу использования памяти при реализации этого свойства.

Извлечение значений именованного кортежа в словарь

      Coords = namedtuple('Coords', ['x', 'y'])
coord=Coords(10,20)
coord._asdict()
   {'x': 10, 'y': 20}

Почему мы используем namedtuple

Если у вас есть этот класс:

      class Stock:
    def __init__(self, symbol, year, month, day, open, high, low, close):
        self.symbol = symbol
        self.year = year
        self.month = month
        self.day = day
        self.open = open 
        self.high = high
        self.low = low
        self.close = close

Классовый подход - против - кортежный подход

      djia.symbol              djia[0]     
djia.open                djia[4]
djia.close               djia[7]
djia.high – djia.low     djia[5] – djia[6]

Как видите, кортежный подход не читается.

Что такое именованный кортеж?

Как следует из названия, namedtuple - это кортеж с именем. В стандартном кортеже мы получаем доступ к элементам, используя индекс, тогда как namedtuple позволяет пользователю определять имя для элементов. Это очень удобно, особенно при обработке файлов csv (значения, разделенные запятыми) и работе со сложным и большим набором данных, когда код становится беспорядочным с использованием индексов (не так уж пифонических).

Как их использовать?

>>>from collections import namedtuple
>>>saleRecord = namedtuple('saleRecord','shopId saleDate salesAmout totalCustomers')
>>>
>>>
>>>#Assign values to a named tuple 
>>>shop11=saleRecord(11,'2015-01-01',2300,150) 
>>>shop12=saleRecord(shopId=22,saleDate="2015-01-01",saleAmout=1512,totalCustomers=125)

чтение

>>>#Reading as a namedtuple
>>>print("Shop Id =",shop12.shopId)
12
>>>print("Sale Date=",shop12.saleDate)
2015-01-01
>>>print("Sales Amount =",shop12.salesAmount)
1512
>>>print("Total Customers =",shop12.totalCustomers)
125

Интересный сценарий обработки CSV:

from csv import reader
from collections import namedtuple

saleRecord = namedtuple('saleRecord','shopId saleDate totalSales totalCustomers')
fileHandle = open("salesRecord.csv","r")
csvFieldsList=csv.reader(fileHandle)
for fieldsList in csvFieldsList:
    shopRec = saleRecord._make(fieldsList)
    overAllSales += shopRec.totalSales;

print("Total Sales of The Retail Chain =",overAllSales)

Внутри Python хорошо используется контейнер, называемый именованным кортежем, он может использоваться для создания определения класса и обладает всеми функциями исходного кортежа.

Использование именованного кортежа будет напрямую применено к шаблону класса по умолчанию для создания простого класса, этот метод позволяет много кода улучшить читаемость, и это также очень удобно при определении класса.

Думаю, стоит добавить информацию о NamedTuples с помощью подсказки типов:

      # dependencies
from typing import NamedTuple, Optional

# definition
class MyNamedTuple(NamedTuple):
    an_attribute: str
    my_attribute: Optional[str] = None
    next_attribute: int = 1

# instantiation
my_named_tuple = MyNamedTuple("abc", "def")
# or more explicitly:
other_tuple = MyNamedTuple(an_attribute="abc", my_attribute="def")

# access
assert "abc" == my_named_tuple.an_attribute
assert 1 == other_tuple.next_attribute

Другой способ (новый способ) использовать именованный кортеж - это использование NamedTuple из набора текста: подсказки типа в namedtuple

Давайте рассмотрим пример верхнего ответа в этом посте, чтобы узнать, как его использовать.

(1) Перед использованием именованного кортежа код выглядит так:

pt1 = (1.0, 5.0)
pt2 = (2.5, 1.5)

from math import sqrt
line_length = sqrt((pt1[0]-pt2[0])**2 + (pt1[1]-pt2[1])**2)
print(line_length)

(2) Теперь мы используем именованный кортеж

from typing import NamedTuple, Number

наследовать класс NamedTuple и определить имя переменной в новом классе. test - это название класса

class test(NamedTuple):
x: Number
y: Number

создавать экземпляры из класса и присваивать им значения

pt1 = test(1.0, 5.0)   # x is 1.0, and y is 5.0. The order matters
pt2 = test(2.5, 1.5)

использовать переменные из экземпляров для расчета

line_length = sqrt((pt1.x-pt2.x)**2 + (pt1.y-pt2.y)**2)
print(line_length)

Попробуй это:

collections.namedtuple()

В принципе, namedtuples легко создавать, легкие типы объектов. Они превращают кортежи в удобные контейнеры для простых задач. С namedtuplesВам не нужно использовать целочисленные индексы для доступа к членам кортежа.

Примеры:

Код 1:

>>> from collections import namedtuple

>>> Point = namedtuple('Point','x,y')

>>> pt1 = Point(1,2)

>>> pt2 = Point(3,4)

>>> dot_product = ( pt1.x * pt2.x ) +( pt1.y * pt2.y )

>>> print dot_product
11

Код 2:

>>> from collections import namedtuple

>>> Car = namedtuple('Car','Price Mileage Colour Class')

>>> xyz = Car(Price = 100000, Mileage = 30, Colour = 'Cyan', Class = 'Y')

>>> print xyz

Car(Price=100000, Mileage=30, Colour='Cyan', Class='Y')
>>> print xyz.Class
Y

Все остальные уже ответили, но я думаю, что мне еще есть что добавить.

Namedtuple может быть интуитивно понят как ярлык для определения класса.

Смотрите громоздкий и традиционный способ определения class,

class Duck:
    def __init__(self, color, weight):
        self.color = color
        self.weight = weight
red_duck = Duck('red', '10')

    In [50]: red_duck
    Out[50]: <__main__.Duck at 0x1068e4e10>
    In [51]: red_duck.color
    Out[51]: 'red'

Что касается namedtuple

from collections import namedtuple
Duck = namedtuple('Duck', ['color', 'weight'])
red_duck = Duck('red', '10')

In [54]: red_duck
Out[54]: Duck(color='red', weight='10')
In [55]: red_duck.color
Out[55]: 'red'
Другие вопросы по тегам