2016-04-06 14 views
0
Ben farkın ne tür İşte sınıfı (dict) ve sınıf (str) arasında var merak ediyorum

benim kodudurpiton sınıfı (dict) ve sınıf (str) arasındaki fark

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

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

Bu sınıflar nelerdir Ben açıklama için yapılmış ve sonra ben neden mydict3 [ 'a'] bir hata yapar aşağıda

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

? yazın Ben yapılan fark olarak bildiğim kadarıyla tek MyDict (dict) ve MyDict (str) , ben (dict, str) c gibi constructeri ama sadece bir şey değildir ++ Belirtilen nesne, java

bana verin Bunun net bir cevabı.

+3

'MyDict3 str'' dan devralan MyDict3 (str) 'demektir' MyDict3 (dict) 'dict'den miras alır. Java’da “MyDict3 sınıfı String’i genişletir” gibi olurdu. –

+3

Dize nesneleri, öğe atamasını desteklemiyor. – vaultah

+0

Anladım, teşekkürler beyler. – tunaBritto

cevap

0

Neden mydict3 ['a'] hata yapıyor? Yaptığım fark sadece MyDict (dict) ve MyDict (str) gibi bildiğim kadarıyla, ben Belirtilen nesne (dict, str) c gibi constructeri ama sadece bir şey değildir ++, java inanıyorum

olduğunu aşağıdaki javascript kodu gibi bir sınıf niteliği ve bir öğe aynı şey olduğunu düşünerek, burada bir karışıklık yapıyoruz:

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

Ama python

foo.a ve foo['a'] iki farklı mekanizmalardır. Kullandığınız erişebilmek sonra

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

:

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

Ama foo['a'] olması Aradığınızda foo.a aslında sınıf tanımının içinden tanımlanan bir sınıfın a niteliğini erişiyorsunuz

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

m O: çalışma, genellikle dicts veya listeler için kullanılan endeksleme mekanizması, kullanmak zorunda echanism sınıfınızın __getitem__ yöntemiyle uygulanmaktadır, bu nedenle isterseniz Eğer aşırı edebilirsiniz:

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' 

Yani, dict sınıf amacıyla, __getitem__ (ve __setitem__ ve diğerleri) uygulayan bir sınıftır sözlük olarak adlandırılan uygun bir haritalama mekanizması sağlayın. Anahtarlar herhangi bir değişmez nesne olabilir ve herhangi bir şeye değer verir. Bir liste için, sadece tam sayı olmalıdır (listedeki pozisyonlar).

söyleniyor

, en sorunuza cevap alalım:

neden mydict3 [ 'a'] bir hata yapar? Liste karakter listesi (eğer gibi size parametre konumuna bir karakter veriyor: Eğer __getitem__ yöntemi için özel bir uygulama olan bir dize, bir uygulama olarak mydict3 tanımlanan çünkü

açıkçası bu kadar C) gibi.

mydict3'u 'a' ile dizine eklemeye çalıştığınızda, python size sorduğunuz şeyin hiçbir anlam ifade etmediğini söyler! Yani sonunda

, derken: yaptığım

fark sadece MyDict (dict) ve MyDict (str)

aslında çok büyük bir fark bu! Bir dict ve bir str aynı arabirime sahip değildir ve bu nedenle yapmak istediğiniz şey çalışmaz!


Not: Aslında hiçbir şey siyah veya beyaz değil. aslında bir sınıfın uygulanması dict olduğunu ve bir örneğinin __dict__ üyesi ile sınıf örneğinin tüm üyelerini erişebilirsiniz:

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

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

ancak doğrudan doğrudan __dict__ örneğini erişmek asla ve yardımcısı kullanmak fonksiyonlar setattr ve getattr:

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

Bu, bazı gelişmiş piton hileler ve onlar dikkatle kullanılması gerekir. gerçekten yapmanın başka yolu yoksa, belki bunu kullanmalısın. Ayrıca

, sınıf üyeleri olarak dict öğeleri dönüşümü özel sınıf vardır, bu namedtuple var:

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

HTH

İlgili konular