2017-04-26 57 views
6

我已经经历了Python文档中的大多数__getitem__的文档,并且也在stackoverflow中,因此这不是重复的问题。但我仍然无法理解它的意义。了解__getitem__方法

所以我能理解的是__getitem__被用来实现像self[key]这样的调用。但是它有什么用处?

可以说我有这样定义一个Python类:

class Person: 
    def __init__(self,name,age): 
     self.name = name 
     self.age = age 

    def __getitem__(self,key): 
     print ("Inside `__getitem__` method!") 
     return getattr(self,key) 

p = Person("Subhayan",32) 
print (p["age"]) 

这将返回的结果符合预期。但为什么首先使用__getitem__?我也听说Python在内部调用__getitem__。但它为什么这样做呢?

有人可以请详细解释一下吗?

+0

这可能是一个例子使用的兴趣:[如何正确地继承dict并覆盖__getitem__&__setitem__ ](http://stackoverflow.com/questions/2390827/how-to-properly-subclass-dict-and-override-getitem-setitem) – roganjosh

+0

在你的例子中使用'__getitem__'没有多大意义,但想象你需要t o编写一个自定义列表或字典类的类,它必须与使用'[]'的现有代码一起工作。这是'__getitem__'有用的情况。 –

回答

7

骢马做了解释什么`的GetItem'用于一个良好的工作 - 但我想给你一个可能有用的例子。 想象一下建筑物的建模。用于建筑,它包括一些属性,其中包括占据每层公司的描述,数据中:

不使用__getitem__,我们将有一个这样的类:

class Building(object): 
    def __init__(self, floors): 
     self._floors = [None]*floors 
    def occupy(self, floor_number, data): 
      self._floors[floor_number] = data 
    def get_floor_data(self, floor_number): 
      return self._floors[floor_number] 

building1 = Building(4) # Construct a building with 4 floors 
building1.occupy(0, 'Reception') 
building1.occupy(1, 'ABC Corp') 
building1.occupy(2, 'DEF Inc') 
print(building1.get_floor_data(2)) 

我们可以使用,无论__getitem__ (和它的对应__setitem__)使建筑类的使用更好。

class Building(object): 
    def __init__(self, floors): 
     self._floors = [None]*floors 
    def __setitem__(self, floor_number, data): 
      self._floors[floor_number] = data 
    def __getitem__(self, floor_number): 
      return self._floors[floor_number] 

building1 = Building(4) # Construct a building with 4 floors 
building1[0] = 'Reception' 
building1[1] = 'ABC Corp' 
building1[2] = 'DEF Inc' 
print(building1[2]) 

无论您使用__setitem__喜欢这真的取决于你打算如何抽象的数据 - 在这种情况下,我们决定把建筑物作为地板的容器(你也可以实现对建筑物的迭代器,甚至可能分片 - 即一次获取多个楼层的数据 - 这取决于你需要什么。

3

[]通过键或索引获取项目的语法只是语法糖。

当你评估a[i] Python调用a.__getitem__(i)(或type(a).__getitem__(a, i),但这种区别是关于继承模型,这里不重要)。即使类a未明确定义此方法,它通常从祖先类继承。

所有(Python 2.7版)的特殊方法的名字和它们的语义在这里列出:https://docs.python.org/2.7/reference/datamodel.html#special-method-names