2016-04-06 2 views
0

Мне интересно, какая разница существует между классом (Dict) и класса (ул) Вот мой кодпитон разница между классом (Dict) и класс (ул)

class MyDict3(str): 
    def __init__(self): 
     self.a = None 

class MyDict(dict): 
    def __init__(self): 
     self.a = None 

Эти классы являются то, что Я сделал для уточнения , а затем набираю ниже

>>> mydict['a'] = 1 
>>> mydict 
{'a': 1} 
>>> mydict3['a'] = 1 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: 'MyDict3' object does not support item assignment 

Почему мой mydict3 [ «а»] сделать ошибку? разница, что я сделал это только MyDict (DICT) и MyDict (ул) Насколько я знаю, объект, который я указал (ДИКТ, ул) не только лишь строителю, как C++, Java

Пожалуйста, дайте мне ясный ответ на это.

+3

'MyDict3 (ул)' означает, что MyDict3 наследует от 'str',' MyDict3 (dict) 'наследует от' dict'. Это будет похоже на «класс MyDict3 extends String» в Java. –

+3

Объекты String не поддерживают назначение элемента. – vaultah

+0

Я понял, спасибо, ребята. – tunaBritto

ответ

0

Почему мой mydict3 ['a'] допустил ошибку? Разница, что я сделал это только MyDict (DICT) и MyDict (ул) Насколько я знаю, объект, который я указал (ДИКТ, ул) не только лишь строителю, как C++, Java

Я считаю, что вы делаете путаницы здесь, думая, что атрибут класса и элемент одно и то же, как и следующий код яваскрипта:

> foo = {'a': 42}; 
{ a: 42 } 
> foo.a 
42 
> foo['a'] 
42 
> foo.a === foo['a'] 
true 

Но в питоне foo.a и foo['a'] два различных механизма. Когда вы звоните foo.a вы на самом деле получить доступ к атрибуту класса, который определяется через определение класса a:

class Foo: 
    def __init__(self): 
     self.a = 42 # declaring and defining the a attribute 

так, то вы можете получить доступ к нему с помощью:

>>> foo = Foo() 
>>> print(foo.a) 
42 

Но иметь foo['a'] работать, вы должны использовать механизм индексации, который обычно используется для dicts или списков:

>>> foo = {'a': 42} 
>>> foo['a'] 
42 

Это м устой реализуется с помощью __getitem__ метода вашего класса, так что вы можете перегрузить его, если вы хотите:

class Foo: 
    def __getitem__(self, val): 
     if val == 'a': 
      return 42 
     raise KeyError('Unknown key') # when the key is unknown, you raise a key error exception 

>>> foo = Foo() 
>>> foo['a'] 
42 
>>> foo['b'] 
KeyError: 'Unknown key' 

Итак, dict класс есть класс, который реализует __getitem____setitem__ и многие другие), для того, чтобы предоставить вам правильный механизм отображения, называемый словарем. Ключи могут быть любыми неизменяемыми объектами и что-то значения. Для списка это должны быть только целые числа (которые являются позициями в списке).

Это, как говорится, давайте ответим на ваш вопрос:

Почему мой mydict3 [ 'а'] сделать ошибку?

, очевидно, это потому, что вы определили mydict3 как реализация строки, которая имеет специальную реализацию метода __getitem__: это дает вам символ в позиции параметра, как если список был список характера (как в C).

Итак, когда вы пытаетесь проиндексировать mydict3 с 'a', python просто говорит вам, что то, что вы просите, не имеет смысла!

Таким образом, в конце концов, когда вы говорите:

Разница, что я сделал это только MyDict (DICT) и MyDict (ул)

на самом деле это очень большая разница! A dict и str не имеют одинакового интерфейса, и поэтому вы не можете работать!


P.S .: На самом деле ничто не является черным или белым. Реализация класса на самом деле является ДИКТ, и вы можете получить доступ ко всем членам экземпляра класса через __dict__ члена экземпляра:

class Foo(): 
    def __init__(self): 
     self.a = 42 

>>> foo = Foo() 
>>> foo.__dict__['a'] 
42 

, но вы никогда не должны непосредственно получить доступ к экземпляру __dict__ непосредственно, а также использовать вспомогательные функции setattr и getattr:

>>> setattr(foo, 'b', 42) 
>>> getattr(foo, 'b') 
42 
>>> getattr(foo, 'a') 
42 

Это некоторые продвинутые приемы питон, и они должны быть использованы с осторожностью. Если есть действительно нет другого способа сделать это, тогда, возможно, вы должны это использовать.

Кроме того, существует специальный класс, преобразование Dict элементов в качестве членов класса, это namedtuple:

>>> from collections import namedtuple 
>>> d = {'a': 42, 'b': 69} 
>>> SpecialDict = namedtuple('SpecialDict', d.keys()) 
>>> foo = SpecialDict(**d) 
>>> d.a 
42 
>>> d.b 
69 

НТН