Облегченные классы с указанными полями в Python

Я ищу что-то очень похожее на namedtuples:

>>> from collections import namedtuple
>>> Party = namedtuple('Party', ['guests', 'location'])
>>> p = Party(['Jed', 'Fred', 'Kathy'], "Steve's House")

вокруг которого я использую класс-оболочку, чтобы добавить расширяемость:

>>> class Party(namedtuple('Party', ['guests', 'location'])):
    ...

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

Я слышал о types.SimpleNamespace, но я не думаю, что он допускает позиционные аргументы при создании (кто-то поправит меня, если я ошибаюсь). Мне нравятся namedtuples, потому что они избавляют меня от необходимости писать __init__, __repr__ и __eq__, которые мне нужны для моего варианта использования.

Что для меня важно: встроенные реализации __init__, __repr__ и __eq__, чтобы мне не приходилось писать их самому. Мне понадобится много (30+) определений этих классов, и некоторые из них будут иметь много (15+) полей.

Что для меня не важно (сейчас): эффективность памяти. Я не планирую иметь более пятисот таких экземпляров одновременно.

Я подумываю о своем собственном, но хочу убедиться, что не изобретаю велосипед заново.


person Eli Rose    schedule 03.08.2015    source источник
comment
Будет ли достаточно использовать атрибут __slots__ в class Party?   -  person chepner    schedule 03.08.2015
comment
Когда вы говорите очень похоже на namedtuple, какие точные качества вы ищете? Если это проблема с местом, то @chepner предлагает использовать __slots__. хороший.   -  person jonrsharpe    schedule 03.08.2015
comment
@jonrsharpe: Да, хороший вопрос. Я хочу __eq__, __repr__ и __init__. Он не должен быть хешируемым или подклассом tuple.   -  person Eli Rose    schedule 03.08.2015
comment
@EliRose, так что размер не является проблемой? Почему бы тебе просто не написать обычный класс?   -  person jonrsharpe    schedule 03.08.2015
comment
@jonrsharpe: у меня будет 50 из них, некоторые со многими полями, и я не хочу переписывать одну и ту же логику __repr__ и __init__ для каждого из них. Итак, для меня важен объем кода, который требуется для определения класса.   -  person Eli Rose    schedule 03.08.2015
comment
@EliRose 50 классов или 50 экземпляров? В нынешнем виде совершенно неясно, о чем вы просите; пожалуйста, отредактируйте вопрос, чтобы уточнить, чего именно вы пытаетесь достичь в целом и почему вы не можете просто написать обычный суперкласс. Вы всегда можете просмотреть исходный код namedtuple. и заимствовать то, что вам нужно от этого.   -  person jonrsharpe    schedule 03.08.2015
comment
Вы правы, спасибо, что помогли мне понять, как лучше донести это. 50 относится к определениям классов.   -  person Eli Rose    schedule 03.08.2015
comment
Python не предназначен для проверки типов, поэтому на самом деле не имеет большого смысла (в некоторых случаях, я признаю, это может иметь смысл) создавать собственные классы для этих легковесных структур данных. Как насчет того, чтобы просто использовать произвольный тип данных?   -  person Alfe    schedule 03.08.2015
comment
@Alfe: выглядит интересно, но я хотел бы иметь возможность указать свои поля в определении класса и выдать ошибку (как это делает namedtuple), если вы попытаетесь создать экземпляр, не предоставив их все.   -  person Eli Rose    schedule 03.08.2015
comment
Вероятно, вы могли бы достичь того, чего хотите, написав один метакласс, который обеспечивает динамическую реализацию __eq__ и т. д., тогда каждый из ваших реальных классов будет его экземпляром, который просто предоставляет имена атрибутов этого класса.   -  person Tom Dalton    schedule 03.08.2015
comment
@TomDalton: Это то, что я собирался сделать, но я хотел убедиться, что не изобретаю велосипед заново. (Похоже, что требуется много кодирования, например, для обеспечения правильной работы подклассов).   -  person Eli Rose    schedule 03.08.2015
comment
FWIW, есть простой способ объединить именованные кортежи. Но я думаю, что это не очень актуально здесь, так как вам нужна изменчивость.   -  person PM 2Ring    schedule 03.08.2015
comment
Какие функции namedtuple делают вы на самом деле нужно? Например, вам нужна числовая индексация и возможность повторения?   -  person PM 2Ring    schedule 03.08.2015
comment
@PM2Ring: мне ничего не нужно, кроме реализации __init__, __repr__ и __eq__.   -  person Eli Rose    schedule 03.08.2015


Ответы (1)


Для задачи вам потребуется 50 определений классов менее чем для пятисот экземпляров. . . в целом ? Может стоит пересмотреть проблему и найти совсем другой подход? Пробовали смотреть словари?

item1 = {'party':'easter', 'guests': ['john', fred','kathy'], 'location':'here'}

Чем вам нужен только стандартный класс Python dict, и вы можете легко проверить наличие поля, добавить поля и т. д., у него есть инициализация, повтор и экв.

Или предоставьте дополнительную информацию о проблеме.

person henkidefix    schedule 13.08.2015