Python是dict一个对象吗?

时间:2013-07-20 10:21:57

标签: python dictionary

我有dict这样:

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

使用has_key输出:

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

使用hasattr输出:

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

我无法理解为什么这种行为会有所不同。 我用Google搜索并发现它是因为dict和对象不同。

但是,我仍然无法正确理解差异。

(顺便说一句:我使用的是python 2.7)

5 个答案:

答案 0 :(得分:24)

dict个实例也是对象。但他们的密钥并没有像属性一样暴露出来。

将密钥暴露为属性(也可以代替项目访问)会导致命名空间污染;例如,你永远无法使用has_key密钥。 has_key 已经是字典上的一个属性:

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

对象的属性和字典的内容是两个单独的事物,分离是故意的。

您始终可以使用__getattr__() hook method

继承dict以添加属性访问权限
class AttributeDict(dict):
    def __getattr__(self, name):
        if name in self:
            return self[name]
        raise AttributeError(name)

演示:

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

dict类上的现有属性优先:

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

答案 1 :(得分:3)

has_key检查字典中是否存在密钥。 (您的代码在创建字典时定义了一个)hasattr检查对象是否具有属性。

字典是对象,它们具有某些属性。 hasattr检查这些。

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

您可以使用dir()列出对象的有效属性。

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

答案 2 :(得分:2)

my_dict.has_key(unicode(2012))has_key在字典中查找密钥。字典中的键不是属性和

  

hasattr(对象,名称)

     

参数是一个对象和一个字符串。该   如果字符串是其中一个对象的名称,则结果为True   属性,否则为假。 (这是通过调用来实现的   getattr(object,name)并查看它是否引发异常或   不。)

你可以从中看到,虽然dict是对象,但是dict的键不是dict的属性;

答案 3 :(得分:1)

Dict是一个对象,因为Python中的任何东西都是一个对象。但是,对象属性和dicts键之间存在差异。 dict不会将其键存储为属性! 访问dicts密钥的唯一方法是通过__getitem__方法或[]运算符。

如果您想以这种方式访问​​这些项目,可以覆盖__getattr__方法并使其返回__getitem__结果。

您还可以创建以下内容:

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

这将导致此行为:

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

但是已知这会导致Python中的内存泄漏

答案 4 :(得分:0)

attribute返回实例的某些属性,以便您可以对其进行操作。 现在了解attribute将始终返回一些内容,但如果key不在d中,则d[key]会引发KeyError

hasattr检查instantce是否有attribute。由于dictionary keysattributedictionary,因此会返回False

示例:

# 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