Python - Словарь - Изменить __getitem__? - PullRequest
3 голосов
/ 21 февраля 2012

Хорошо, поэтому я создал свой собственный обработчик переменных, который имеет функцию __getitem__ для использования при доступе к данным через данные [ключ], он отлично работает, за исключением случаев, когда пытаются получить доступ к ссылке элементов:

data["key"]["subkey"]


def __getitem__(self, key, **args):
    print key
    ...
    return self.dict[key]

При попытке получить доступ к подразделу, который не существует, Python просто возвращает KeyError без печати «subkey», почему это так и как я могу заставить Python распечатать то, что я на самом деле пытаюсь получить?

Я знаю, что я, вероятно, неправильно понял механику, но есть ли способ эмулировать словарь И следовать последовательности запрашиваемых данных?Главным образом, чтобы я мог динамически регистрировать отсутствующие переменные в потоке словаря ...

Это, очевидно, работает (но мне не нравится родной синтаксис):

data["key:subkey"]

def __getitem__(self, key, **args):
    for slice in key.split(':'):
        print key
    ...

Цель состоит в том, чтобыэмулируйте следующее:

Работает:

data = {'key' : {'subkey' : 1}}
print data["key"]["subkey"]

Не будет работать, но я хочу перехватить исключение в __getitem__, а затем автоматически создать отсутствующий ключ или просто зарегистрировать отсутствующий подраздел:

data = {'key' : {}}
print data["key"]["subkey"]

Решение:

class Var():
    def __init__(self):
        self.dict = {'test' : {}}
    def __getitem__(self, var, **args):
        print ':',var
        if var in self.dict:
            v = Var(self.dict[var])
            return v

print vHandle['test']['down']

Вывод:

: тест

: вниз

Нет

Ответы [ 2 ]

5 голосов
/ 21 февраля 2012

Дело в том, что когда Python встречает выражение, такое как data["key"]["subkey"], то внутренне выполняется (data["key"])["subkey"]. То есть разрешена первая часть выражения: извлечение элемента «ключ» из объекта «данные». Затем Python пытается сделать вызов __getitem__ для полученного объекта этого выражения. Если такой результирующий объект не имеет самого метода __getitem__, это ваша ошибка.

Есть два возможных обходных пути: вы должны либо работать с «индексами кортежей» - как data["key", "subkey"] (а затем протестируйте метод __getitem__, если в качестве ключа вы получили экземпляр кортежа) - или заставьте __getitem__ вернуть специализированный объект, который также имеет метод __getitem__ - даже если все, что он делает, это регистрирует запрошенные ключи.

4 голосов
/ 21 февраля 2012

Помните: tmp = foo['bar']['baz'] совпадает с tmp = foo['bar']; tmp = tmp['baz']

Таким образом, чтобы разрешить произвольную глубину, ваш метод __getitem__ должен возвращать новый объект, который также содержит такой метод __getitem__.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...