2013-07-20 54 views
9

Tôi có một dict như thế này:Python có phải là một đối tượng không?

>>> my_dict = {u'2008': 6.57, u'2009': 4.89, u'2011': 7.74, 
...   u'2010': 7.44, u'2012': 7.44} 

Output với has_key:

>>> my_dict.has_key(unicode(2012)) 
True 

Output với hasattr:

>>> hasattr(my_dict, unicode(2012)) 
False 

Tôi không thể hiểu tại sao điều này cư xử khác nhau. Tôi googled và phát hiện ra rằng đó là vì dict và các đối tượng khác nhau.

Nhưng, tôi vẫn không thể hiểu sự khác biệt chính xác.

(BTW: Tôi đang sử dụng python 2,7)

+3

Nhân tiện: 'has_key' bị * không dùng nữa * và đã bị xóa trong python3. Sử dụng 'the_key trong the_dictionary' để thay thế. – Bakuriu

Trả lời

21

dict cũng là các đối tượng. Nhưng chìa khóa của họ chỉ là không tiếp xúc như là thuộc tính.

Hiển thị khóa là thuộc tính (quá hoặc thay vì truy cập mục) sẽ dẫn đến ô nhiễm không gian tên; bạn không bao giờ có thể sử dụng khóa has_key. has_keyđã một thuộc tính trên các từ điển:

>>> hasattr({}, 'has_key') 
True 
>>> {}.has_key 
<built-in method has_key of dict object at 0x7fa2a8461940> 

Thuộc tính của các đối tượng và nội dung của từ điển là hai riêng vật, và sự tách biệt là có chủ ý.

Bạn luôn có thể phân lớp dict thêm truy cập thuộc tính bằng cách sử dụng __getattr__() hook method:

class AttributeDict(dict): 
    def __getattr__(self, name): 
     if name in self: 
      return self[name] 
     raise AttributeError(name) 

Demo:

>>> demo = AttributeDict({'foo': 'bar'}) 
>>> demo.keys() 
['foo'] 
>>> demo.foo 
'bar' 

hiện thuộc tính trên ưu tiên mất dict lớp:

>>> demo['has_key'] = 'monty' 
>>> demo.has_key 
<built-in method has_key of AttributeDict object at 0x7fa2a8464130> 
+0

Bạn quá nhanh với tôi: -/Tôi muốn viết một câu trả lời tương tự, nhưng sau đó tôi thấy "3 câu trả lời mới" ... –

+4

@moose: Vào cuối tuần sự cân bằng giữa người hỏi câu hỏi và người trả lời dường như bị lệch một chút đối với người trả lời .. :-) –

+0

Cảm ơn bạn @ martijn-pieters, lời giải thích thực sự tốt đẹp, tôi không thể hiểu về sự ô nhiễm không gian tên, bạn có thể vui lòng giải thích rằng với tôi? –

3

has_key kiểm tra cho sự tồn tại của một chìa khóa trong từ điển. (Một mã của bạn xác định khi tạo từ điển) hasattr kiểm tra xem đối tượng có thuộc tính hay không.

Từ điển là các đối tượng và chúng có các thuộc tính nhất định. hasattr kiểm tra cho những người đó.

>>> hasattr(dict, 'has_key') 
True 
>>> hasattr(dict, 'items') 
True 
>>> newDict = {'a': 1, 'b':2} 
>>> newDict.has_key('a') 
True 

Bạn có thể sử dụng dir() để liệt kê các thuộc tính hợp lệ cho một đối tượng.

>>> dir(dict) 
['__class__', '__cmp__', '__contains__', '__delattr__', '__delitem__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'clear', 'copy', 'fromkeys', 'get', 'has_key', 'items', 'iteritems', 'iterkeys', 'itervalues', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values', 'viewitems', 'viewkeys', 'viewvalues'] 
0

attribute trả về một số thuộc tính của một thể hiện để bạn có thể thao tác nó. Bây giờ, hãy hiểu rằng attribute sẽ luôn trả lại nội dung nào đó, nhưng nếu số key không nằm trong số d, d[key] sẽ tăng KeyError.

hasattr kiểm tra xem instantceattribute hay không.Vì dictionarykeys không phải là attribute đến dictionary, nó trả về False.

dụ:

# python3 
>>> d = {1:True} 
>>> dir(d) # this shows all the attributes of the instance 
['__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__' 
, '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', 
'__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '_ 
_new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__' 
, '__sizeof__', '__str__', '__subclasshook__', 'clear', 'copy', 'fromkeys', 'get 
', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values'] 
>>> hasattr(d,'keys') 
True 
>>> 1 in d.keys() 
True 
+0

* thuộc tính có nghĩa là phương thức lớp hoặc hằng số *. Không, thuộc tính nghĩa là thuộc tính. Các hàm là các thuộc tính, cùng với [giao thức mô tả] (http://docs.python.org/2/howto/descriptor.html) làm cho chúng trở lại như các phương thức.Thuộc tính là các thuộc tính và mô tả. Bạn có thể lưu trữ các hàm trên các cá thể dưới dạng các thuộc tính, sau đó chúng có thể gọi được nhưng không phải là các phương thức. Vv Không có hằng số trong Python. –

+0

không có nghĩa là lớp liên tục. xin lỗi tôi đã viết sai. Những gì tôi có nghĩa là, thuộc tính có nghĩa là, một cái gì đó mà làm một số loại hoạt động trên một đối tượng và trả lại một số đối tượng khác. trong khi đó, các khóa dict hoàn toàn khác nhau. Tôi có thể sai, cho tôi biết thêm hoặc cho tôi một số liên kết. – rnbcoder

+1

Tham chiếu chuẩn là [tài liệu Python datamodel] (http://docs.python.org/2/reference/datamodel.html). –

1

Dict là một đối tượng, như bất cứ điều gì trong Python là một đối tượng. Tuy nhiên, có một sự khác biệt giữa một thuộc tính đối tượng và một khóa dicts. Các dict không lưu trữ các phím của nó như là thuộc tính! Cách duy nhất để truy cập khóa dicts là qua phương thức __getitem__ hoặc toán tử [].

Nếu bạn muốn truy cập các mục theo cách này, bạn có thể ghi đè phương pháp __getattr__ và trả về kết quả là __getitem__.

Bạn cũng có thể tạo ra một cái gì đó như thế này:

class ObjectDict(dict): 
     def __init__(self, *args, **kws): 
      super(ObjectDict, self).__init__(*args, **kws) 
      self.__dict__ = self

Mà sẽ dẫn đến hành vi này:

 
>>> d = ObjectDict() 
>>> d['a'] = 3 
>>> d.a 
3 
>>> hasattr(d, 'a') 
True 

Nhưng điều này được biết là gây ra rò rỉ bộ nhớ trong Python

2

my_dict.has_key(unicode(2012)): has_key tìm một khóa trong từ điển. Keys trong một cuốn từ điển không phải là thuộc tính và

hasattr (đối tượng, tên)

Các đối số là một đối tượng và một chuỗi. Kết quả là Đúng nếu chuỗi là tên của một trong các thuộc tính của đối tượng, Sai nếu không. (Điều này được thực hiện bằng cách gọi getattr (đối tượng, tên) và nhìn thấy cho dù đó đặt ra một ngoại lệ hoặc không.)

mà từ đó bạn có thể thấy rằng, mặc dù dict được các đối tượng, các phím dict của không thuộc tính của dict ;

Các vấn đề liên quan