Об этом, кстати, (различии между offset и index) тоже писалось в обсуждении. Но, по факту, списки унаследовали индексацию с нуля от массивов, но в массивах это было разумно, по указанным вами причинам, а в списках вроде как не совсем (или не всем).
Предложение как раз и заключалось в том, чтобы отказаться от этого наследства и перейти к человечной нумерации.
Уважаемый tanenn очень хорошо описал отношение к этой «фишке» в комментарие выше: habrahabr.ru/blogs/python/129201/#comment_4276323
Конечно, если вам нужен словарь, как «очень эффективная структура, с точки зрения времени доступа к данным», то никакой синтаксический сахар и вообще любые слои над стандартной библиотекой ни к чему.
«Нормализация имеет своей целью избавиться от избыточности в отношениях и модифицировать их структуру таким образом, чтобы процесс работы с ними не был обременён различными посторонними сложностями.»
Мне кажется, что само задание __slots__ противоречит самой идее, что объект является словарем, в который можно добавлять/изменять/удалять свойства. Объясните, если я не прав.
Вы правы. Расширенную реализацию идеи, с использованием метакласса, которая частично решает проблему:
def validDictProperty(name, value):
return not callable(value) and not isinstance(value, (property, classmethod, staticmethod))
class DictMetaclass(type):
def __init__(cls, name, bases, namespace):
cls.default = {}
for base in bases:
if hasattr(base, "default"):
cls.default.update(base.default)
cls.default.update((k, v) for k, v in namespace.items() if validDictProperty(k, v))
class Dict(dict):
__metaclass__ = DictMetaclass
def __new__(cls, *args, **kwargs):
self = dict.__new__(cls)
self.update(cls.default)
self.__dict__ = self
return self
Такая реализация во-первых позволяет объектам иметь методы, определенные в класах-наследниках Dict, которые при этом не будут элементами словаря, а во-вторых поддерживаются как атрибуты и как элементы свойства по-умолчанию, определенные в класах-наследниках.
не знаю как у вас, но у меня после ваших манипуляций foo.update возвращает 'bar'. Но это порождает другую проблему: перекрытие нативных методов с последующими трудноуловимыми багами там, где они используются.
Да, рекурсивный вариант не предполагался, хотя можно написать так: Dict({'a':1,'b':Dict({'c':3,'d':4})}).
Кстати, рекурсивным вариантом вроде того, что вы предложили, очень удобно оборачивать какие-то распаршеные конфиги или другие данные, полученные из yaml или json для последующей работы с ними.
В такой реализации атрибуты объекта и ЕСТЬ значениями в словаре (не считая нативных методов класа dict), так что они не могут «путаться». Хотя да, согласен проблемы могут вылезти, например, если отнаследоватся от Dict и добавить в него новые свойства, они не будут видны как значения(item) в словаре-экземпляре этого класа, хотя будут видны как атрибуты(attr). Но эту проблему можно решить с помощью метакласа, что, по секрету, и было сделанно в системе, где это используются.)
Такая ситуация не будет мешать нативным фунцкиям словаря, так что всегда остается возможность написать a["copy"].
Интерфейс доступа к данным остался один, только теперь его можно синтаксически написать по-разному: оба варианта работают эквивалентно.
Предложение как раз и заключалось в том, чтобы отказаться от этого наследства и перейти к человечной нумерации.
Конечно, если вам нужен словарь, как «очень эффективная структура, с точки зрения времени доступа к данным», то никакой синтаксический сахар и вообще любые слои над стандартной библиотекой ни к чему.
Укажите в опросе, что имеется ввиду php.
Такая реализация во-первых позволяет объектам иметь методы, определенные в класах-наследниках Dict, которые при этом не будут элементами словаря, а во-вторых поддерживаются как атрибуты и как элементы свойства по-умолчанию, определенные в класах-наследниках.
foo.update
возвращает'bar'
. Но это порождает другую проблему: перекрытие нативных методов с последующими трудноуловимыми багами там, где они используются.Dict({'a':1,'b':Dict({'c':3,'d':4})})
.Кстати, рекурсивным вариантом вроде того, что вы предложили, очень удобно оборачивать какие-то распаршеные конфиги или другие данные, полученные из yaml или json для последующей работы с ними.
a["copy"]
.Интерфейс доступа к данным остался один, только теперь его можно синтаксически написать по-разному: оба варианта работают эквивалентно.