Существует ли существующий класс Python, который может содержать любые пользовательские атрибуты?

Я могу использовать это, когда мне нужно несколько объектов с разными атрибутами:

class struct(object):
   def __init__(self,*args,**kwargs):
      for key,val in kwargs.items():
         setattr(self,key,val)

Но мне интересно, нет ли уже встроенного?


person Geo    schedule 13.11.2009    source источник
comment
кажется, вы ищете что-то вроде этого: stackoverflow.com/questions/1528932/   -  person SilentGhost    schedule 13.11.2009


Ответы (3)


Если я не понимаю вашего вопроса, разве не для этого мы используем dict? Конечно, нотация немного отличается, но атрибуты объекта внутри по-прежнему хранятся в dict (а именно __dict__). Это вопрос обозначений.

Но, если вы настаиваете, то это один из способов сделать это:

>>> class struct(dict):
...     def __getattribute__(self, key):
...         return self[key]
... 
>>> s = struct(a=5, b=7)
>>> s.a
5

Примечание. Я использую __getattribute__ вместо __getattr__. Причина этого в том, что в противном случае мы не можем хранить атрибуты с такими именами, как get и keys, поскольку это методы, определенные dict.

решение SilentGhost, вероятно, эффективнее и работает так же хорошо, не прибегая к использованию __getattribute__. Затем код становится:

>>> def struct(**kwargs):
...     return type('Struct', (object,), kwargs)
... 
>>> s = struct(a=5, b=7)
>>> s.a
5
person Stephan202    schedule 13.11.2009

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

x = {}
x.update([(1, 2), (3, 4), (5, 6)])
print x

результат

{1: 2, 3: 4, 5: 6}

or

x.update(a=2, b=4, c=6)

приводит к

{'a': 2, 'c': 6, 'b': 4}
person Bryan McLemore    schedule 13.11.2009

Я задавался вопросом о том же. Мне нравится удобство x.foo вместо x["foo"]; одну точку гораздо легче напечатать (и сделать это правильно), чем все [""].

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

Вот основная версия этой идеи:

class struct(object):
    pass

x = struct()
x.foo = 1

Пока вы собираетесь так много хлопот, вы можете также добавить __init__(), который обрабатывает kwargs для удобной инициализации. Но мне лень и я надеялся на что-то встроенное.

Я пробовал это, что не работает:

x = object()
x.foo = 1   # raises AttributeError exception

Я спросил об этом и получил ответ, что object является корнем всех типов в Python; это как можно меньше. Если бы он мог действовать как экземпляр класса со своим собственным атрибутом __dict__, то каждый объект, когда-либо созданный в Python, нуждался бы в присоединенном __dict__.

Я бы хотел, чтобы struct был добавлен как встроенный для Python 3.x. Но я понимаю, почему это было не так: сохранить язык небольшим и чистым — достойная цель, и эту функцию тривиально легко написать самостоятельно.

person steveha    schedule 13.11.2009
comment
Хороший анализ. Позвольте мне добавить две вещи: (1) это свойство object, заключающееся в том, что у него нет __dict__, можно также использовать для других классов, определив __slots__ (см. docs.python.org/reference/datamodel.html#slots для получения дополнительной информации); (2) относительно вашего последнего абзаца: import this утверждает: Должен быть один -- и желательно только один -- очевидный способ сделать это. - person Stephan202; 13.11.2009