Вы могли использовать эту стратегию, описал здесь как лучшую практику (2006) или обновленная стратегия, описанная здесь (2015):
Этот подход обеспечивает защиту подробно. Если кому-то удается пропустить таблицу базы данных, она не дает взломщику открытую дверь для исполнения роли пользователей.
Питонический способ заключался бы в использовании dict
:
>>> foo = dict(x=1, y=2)
>>> bar = dict(y=2, x=1)
>>> foo == bar
True
Отвечает всем вашим требованиям, за исключением того, что вам все еще нужно выполнить foo ['x']
вместо foo.x
.
Если это проблема, вы можете легко определить класс, например:
class Bunch(object):
def __init__(self, **kwds):
self.__dict__.update(kwds)
def __eq__(self, other):
return self.__dict__ == other.__dict__
Или красивый и короткий
class Bunch(dict):
__getattr__, __setattr__ = dict.get, dict.__setitem__
(но обратите внимание, что у второго есть проблемы, как указывает Алекс в своем комментарии!)
1) См. http://uszla.me.uk/space/blog / 2008/11/06 . Вы можете создать анонимный объект со слегка некрасивым синтаксисом, используя встроенную функцию type
:
anon_object_2 = type("", (), {})()
где третий параметр - это словарь, который будет содержать поля вашего объекта.
foo = type("", (), dict(y=1))()
foo.y == 1
2) Другой вариант предложен Питером Норвигом на http://norvig.com/python-iaq.html . Он также похож на ответ, опубликованный Кеном.
class Struct:
def __init__(self, **entries): self.__dict__.update(entries)
>>> options = Struct(answer=42, linelen = 80, font='courier')
>>> options.answer
42
Преимущество этого метода в том, что вы можете реализовать равенство по содержимому dict, чего нет в первом варианте.
Форма типа (...) не выполнит требование структурного сравнения (не получится действительно некрасиво). Форма dict (...) не соответствует требованиям доступа к атрибуту.
attrdict , кажется, находится где-то посередине:
class attrdict(dict):
def __init__(self, *args, **kwargs):
dict.__init__(self, *args, **kwargs)
self.__dict__ = self
a = attrdict(x=1, y=2)
b = attrdict(y=2, x=1)
print a.x, a.y
print b.x, b.y
print a == b
Но это означает определение специального класса.
ОК, только что заметил обновление вопроса. Замечу лишь, что вы можете указать dict
для параметра баз, и тогда нужно будет указать только конструктор (в выражении неприглядного типа). Я предпочитаю attrdict. : -)
Навскидку не помню, есть ли встроенный, но написать его самому короче, чем ввести свой вопрос. : -)
class record(object):
def __init__(self, **kwargs): self.__dict__ = kwargs
def __eq__(self, r2): return self.__dict__ == r2.__dict__
def __ne__(self, r2): return self.__dict__ != r2.__dict__
foo = record(x=1, y=2)
bar = record(y=2, x=1)
foo == bar # => true
Цитируется из этой страницы :
class Struct:
def __init__(self, **entries): self.__dict__.update(entries)
def __eq__(self, other): return self.__dict__ == other.__dict__
def __ne__(self, other): return self.__dict__ != other.__dict__
options = Struct(answer=42, linelen = 80, font='courier')
options.answer
>>> 42
options.answer = 'plastics'
vars(options)
>>> {'answer': 'plastics', 'font': 'courier', 'linelen': 80}