2009-05-03 3 views

ответ

8

Вы можете легко расширить любой встроенный тип. Это, как вы могли бы сделать это с Dict:

>>> class MyClass(dict): 
...  def __init__(self, *args, **kwargs): 
...    self['mykey'] = 'myvalue' 
...    self['mykey2'] = 'myvalue2' 
... 
>>> x = MyClass() 
>>> x['mykey'] 
'myvalue' 
>>> x 
{'mykey2': 'myvalue2', 'mykey': 'myvalue'} 

Я не смог найти в документации на Python, который говорит об этом, но очень популярная книга Dive Into Python (доступен для свободного онлайн) has a few examples делать это ,

+0

А, спасибо, что насытили мое любопытство. –

+2

Я думаю, вы должны добавить вызов dict .__ init__ от http://stackoverflow.com/questions/817884/creating-dictionaries-with-pre-defined-keys/818019#818019 (или даже лучше, пользовательский супер). –

+0

Вот как у меня это было изначально (проверьте историю), но после некоторых исследований вы, очевидно, не нуждаетесь в этом в этом случае. Согласно приведенной выше ссылке Dive Into Python: «dict не работает так: это не оболочка, и она не требует явной инициализации». - Мне бы хотелось узнать больше об этом, так как это был мой первый инстинкт, чтобы там был супер-звонок. –

0

Просто создайте подкласс dict и добавьте ключи в метод init.

 
class MyClass(dict) 

def __init__(self): 
    """Creates a new dict with default values"""" 

    self['key1'] = 'value1' 

Помните, что в питоне любой класс, который «действует как Словаре» обычно трактуется как один, так что вам не придется беспокоиться об этом слишком много быть подклассом, вы могли бы вместо того, чтобы реализовать Dict методы, хотя вышеупомянутый подход, вероятно, более полезен для вас :).

3

Да, в Python dict это класс, так что вы можете подкласс:

class SubDict(dict): 
     def __init__(self): 
      dict.__init__(self) 
      self.update({ 
       'foo': 'bar', 
       'baz': 'spam',}) 

Здесь вы переопределить __init__() метод Dict в (метод, который вызывается, когда экземпляр класса создается). Внутри __init__ вы впервые вызываете метод supercalss __init__(), который является обычной практикой, когда вы хотите расширить функциональность базового класса. Затем вы обновляете новый экземпляр SubDictionary с вашими исходными данными.

subDict = SubDict() 
    print subDict # prints {'foo': 'bar', 'baz': 'spam'} 
8

Вы также можете иметь ДИКТ подкласс ограничивает ключи к заранее определенному списку, с помощью переопределения __setitem__()

>>> class LimitedDict(dict): 
    _keys = "a b c".split() 
    def __init__(self, valtype=int): 
     for key in LimitedDict._keys: 
      self[key] = valtype() 
    def __setitem__(self, key, val): 
     if key not in LimitedDict._keys: 
      raise KeyError 
     dict.__setitem__(self, key, val) 


>>> limited = LimitedDict() 
>>> limited['a'] 
0 
>>> limited['a'] = 3 
>>> limited['a'] 
3 
>>> limited['z'] = 0 

Traceback (most recent call last): 
    File "<pyshell#61>", line 1, in <module> 
    limited['z'] = 0 
    File "<pyshell#56>", line 8, in __setitem__ 
    raise KeyError 
KeyError 
>>> len(limited) 
3 
+0

+1 для дополнительной информации –

+0

Это идеальное решение для меня, спасибо! Однако не могли бы вы объяснить, почему вы объявляете свойство «_keys» с символом подчеркивания в начале? –

+0

Поздний отклик, но ведущим подчеркиванием является неофициальное обозначение, указывающее, что член является локальным («защищенным»). –

1

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

В отличие от Perl, который будет делать это для вас по умолчанию,


grep{$_{$_}++} qw/ a a b c c c /; 
print map{$_."\t".$_{$_}."\n"} sort {$_{$b}$_{$a}} keys %_; 

c 3 
a 2 
b 1 

Python не даст вам это бесплатно:


l = ["a","a","b","c","c","c"] 
d = {} 
for item in l: 
    d[item] += 1 

Traceback (most recent call last): 
    File "./y.py", line 6, in 
    d[item] += 1 
KeyError: 'a' 

однако defaultdict будет делать это для вас,


from collections import defaultdict 
from operator import itemgetter 

l = ["a","a","b","c","c","c"] 
d = defaultdict(int) 
for item in l: 
    d[item] += 1 

dl = sorted(d.items(),key=itemgetter(1), reverse=True) 
for item in dl: 
    print item 

('c', 3) 
('a', 2) 
('b', 1) 
+0

Не то, что я хотел, но спасибо за попытку. –

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