2012-02-21 4 views
3

Ok, поэтому я построю свой собственный переменный обработчик, который имеет __getitem__ функцию для использования при доступе к данным с помощью данных [ключевых], она отлично работает при попытке получить доступ к ссылке пунктов, за исключением:Python - Словарь - Изменить __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__, а затем создать ми ключ ssing автоматически или просто войти отсутствующий раздел:

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'] 

Выход:

: тест

: вниз

None

+0

Я что-то пропустил здесь, или это вообще не заслуживает нисходящего движения? Мог ли дайвервитер объяснить себя? – Polynomial

+0

Каков тип 'data'? Каков тип 'data [" key "]'? Вероятно, вам нужно показать больше кода, иначе все, что мы можем сделать, это догадываться. (Не мой нисходящий) –

+2

Нет, вы не можете сделать это напрямую (вы можете, вернув обернутый объект, делающий то же самое). Подумайте об этом так: '_ = data ['key']', а затем '_ ['subkey']'. Вы могли бы альтернативно иметь «data ['key', 'subkey']' (ключи кортежа), если это был действительный способ доступа к данным. –

ответ

5

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

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

+0

Так вот как это работает, я только предположил, что python автоматически вызовет __getitem__ через тот же экземпляр переменной снова после первого ключа, я предполагаю, что мне нужно вернуть второй экземпляр моего дескриптора переменной, чтобы __getitem__ существовал для второго вызова , Спасибо! – Torxed

4

Помните: tmp = foo['bar']['baz'] такие же, как tmp = foo['bar']; tmp = tmp['baz']

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

+0

Я предполагаю, что мне нужно вернуть второй экземпляр моего дескриптора переменной из «обработчика переменной», так что __getitem__ существует и для второго вызова. Спасибо! – Torxed

Смежные вопросы