Существует ли существующий класс Python, который может содержать любые пользовательские атрибуты? - PullRequest
2 голосов
/ 13 ноября 2009

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

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

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

Ответы [ 3 ]

9 голосов
/ 13 ноября 2009

Если я не понимаю ваш вопрос, не для этого ли мы используем 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
3 голосов
/ 13 ноября 2009

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

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

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

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. Но я понимаю, почему этого не произошло: поддерживать язык маленьким и чистым - это достойная цель, и эту функцию легко написать самостоятельно.

3 голосов
/ 13 ноября 2009

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

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

результат

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

или

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

Результаты в

{'a': 2, 'c': 6, 'b': 4}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...