Created
June 22, 2009 13:50
-
-
Save riffm/133971 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
class MultiValueDict(dict): | |
""" | |
Словарь с возможностью соответствия | |
нескольких значений одному ключу. | |
>>> list_ = (('foo','bar'),('spam','eggs'),('foo','baz')) | |
>>> md = MultiValueDict(list_) | |
>>> md['foo'] | |
['bar', 'baz'] | |
>>> md['spam'] | |
['eggs'] | |
>>> md.getlist('foo') | |
['bar', 'baz'] | |
""" | |
def __init__(self, initial_data={}, *args, **kwargs): | |
""" | |
initial_data -> либо список кортежей | |
((key1, value1), (key2, value2), ...(key1, value2)) | |
либо обычный словарь, либо экземпляр MultiValueDict | |
>>> list_ = (('foo','bar'),('spam','eggs'),('foo','baz')) | |
>>> md = MultiValueDict(list_) | |
>>> print md | |
MultiValueDict([('foo', 'bar'), ('foo', 'baz'), ('spam', 'eggs')]) | |
>>> new_md = MultiValueDict(md) | |
>>> print new_md | |
MultiValueDict([('foo', 'bar'), ('foo', 'baz'), ('spam', 'eggs')]) | |
""" | |
super(MultiValueDict, self).__init__(*args, **kwargs) | |
if hasattr(initial_data, 'items'): | |
# Предполагаем, что initial_data - словарь или экземпляр | |
# MultiValueDict. Просто сохранить копию словаря нельзя, потому что | |
# внутреннее представление данных - словарь, каждому | |
# ключу которого соответствует список значений | |
initial_data = initial_data.items() | |
for key, value in initial_data: | |
self.append(key, value) | |
def append(self, key, value): | |
""" | |
Метод добавляет значение ключу, при этом, | |
если ключа не существует, то он создается. | |
>>> md = MultiValueDict() | |
>>> md.append('foo', 'bar') | |
>>> md.append('foo', 'baz') | |
>>> md.append('spam', 'eggs') | |
>>> print md | |
MultiValueDict([('foo', 'bar'), ('foo', 'baz'), ('spam', 'eggs')]) | |
""" | |
self.setdefault(key, []).append(value) | |
getlist = dict.__getitem__ | |
def __setitem__(self, key, value): | |
""" | |
Метод принимает ключ и список или кортеж | |
значений. | |
>>> md = MultiValueDict() | |
>>> md['foo'] = 'bar'# doctest: +IGNORE_EXCEPTION_DETAIL | |
Traceback (most recent call last): | |
AssertionError: Values must be type list or tuple | |
>>> md['foo'] = ['spam', 'eggs'] | |
>>> print md | |
MultiValueDict([('foo', 'spam'), ('foo', 'eggs')]) | |
>>> md.setlist('foo', ['bar', 'baz']) | |
>>> print md | |
MultiValueDict([('foo', 'bar'), ('foo', 'baz')]) | |
""" | |
assert isinstance(value, list),\ | |
"Values must be type list" | |
super(MultiValueDict, self).__setitem__(key, value) | |
setlist = __setitem__ | |
def items(self): | |
""" | |
Метод возвращает кортежи (key, value), если у | |
ключа несколько значений, то будет возвращено | |
несколько кортежей (key, value1), (key, value2) | |
>>> md = MultiValueDict() | |
>>> md['foo'] = ['bar','baz'] | |
>>> md['spam'] = ['eggs',] | |
>>> md.items() | |
[('foo', 'bar'), ('foo', 'baz'), ('spam', 'eggs')] | |
""" | |
return list(self.iteritems()) | |
def iteritems(self): | |
for k,v in super(MultiValueDict, self).iteritems(): | |
for item in v: | |
yield (k, item) | |
def copy(self): | |
return self.__class__(self) | |
def __repr__(self): | |
return '%s(%r)' % (self.__class__.__name__, self.items()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment