Python 理解 __getitem__ 方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/43627405/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 23:14:45  来源:igfitidea点击:

Understanding __getitem__ method

python

提问by user1867151

I have gone through most of the documentation of __getitem__in the Python docs, but I am still unable to grasp the meaning of it.

我已经浏览__getitem__了 Python 文档中的大部分文档,但我仍然无法理解它的含义。

So all I can understand is that __getitem__is used to implement calls like self[key]. But what is the use of it?

所以我能理解的是,__getitem__它用于实现像self[key]. 但是它有什么用呢?

Lets say I have a python class defined in this way:

假设我有一个以这种方式定义的 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"])

This returns the results as expected. But why use __getitem__in the first place? I have also heard that Python calls __getitem__internally. But why does it do it?

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

Can someone please explain this in more detail?

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

回答by Tony Suffolk 66

Cong Ma does a good job of explaining what __getitem__is used for - but I want to give you an example which might be useful. Imagine a class which models a building. Within the data for the building it includes a number of attributes, including descriptions of the companies that occupy each floor :

Cong Ma 很好地解释了__getitem__用于什么- 但我想给你一个可能有用的例子。想象一个对建筑物建模的类。在建筑物的数据中,它包括许多属性,包括对占据每层楼的公司的描述:

Without using __getitem__we would have a class like this :

如果不使用,__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) )

We could however use __getitem__(and its counterpart __setitem__) to make the usage of the Building class 'nicer'.

然而,我们可以使用__getitem__(及其对应物__setitem__)来使 Building 类的使用“更好”。

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

Whether you use __setitem__like this really depends on how you plan to abstract your data - in this case we have decided to treat a building as a container of floors (and you could also implement an iterator for the Building, and maybe even the ability to slice - i.e. get more than one floor's data at a time - it depends on what you need.

你是否__setitem__像这样使用真的取决于你计划如何抽象你的数据 - 在这种情况下,我们决定将建筑物视为楼层的容器(你也可以为建筑物实现一个迭代器,甚至可能具有切片的能力- 即一次获取多个楼层的数据 - 这取决于您的需要。

回答by Cong Ma

The []syntax for getting item by key or index is just syntax sugar.

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

When you evaluate a[i]Python calls a.__getitem__(i)(or type(a).__getitem__(a, i), but this distinction is about inheritance models and is not important here). Even if the class of amay not explicitly define this method, it is usually inherited from an ancestor class.

当您评估a[i]Python 调用时a.__getitem__(i)(或type(a).__getitem__(a, i),但这种区别与继承模型有关,在这里并不重要)。即使类a可能没有明确定义这个方法,它通常是从祖先类继承而来的。

All the (Python 2.7) special method names and their semantics are listed here: https://docs.python.org/2.7/reference/datamodel.html#special-method-names

所有(Python 2.7)特殊方法名称及其语义都列在此处:https: //docs.python.org/2.7/reference/datamodel.html#special-method-names

回答by user3503692

The magic method __getitem__is basically used for accessing list items, dictionary entries, array elements etc. It is very useful for a quick lookup of instance attributes.

魔术方法__getitem__主要用于访问列表项、字典条目、数组元素等。它对于快速查找实例属性非常有用。

Here I am showing this with an example class Person that can be instantiated by 'name', 'age', and 'dob' (date of birth). The __getitem__method is written in a way that one can access the indexed instance attributes, such as first or last name, day, month or year of the dob, etc.

在这里,我用一个示例类 Person 展示了这一点,该类可以通过“姓名”、“年龄”和“dob”(出生日期)进行实例化。该__getitem__方法以一种可以访问索引实例属性的方式编写,例如名字或姓氏、日期、月份或年份等。

import copy

# Constants that can be used to index date of birth's Date-Month-Year
D = 0; M = 1; Y = -1

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

    def __getitem__(self, indx):
        print ("Calling __getitem__")
        p = copy.copy(self)

        p.name = p.name.split(" ")[indx]
        p.dob = p.dob[indx] # or, p.dob = p.dob.__getitem__(indx)
        return p

Suppose one user input is as follows:

假设一个用户输入如下:

p = Person(name = 'Jonab Gutu', age = 20, dob=(1, 1, 1999))

With the help of __getitem__method, the user can access the indexed attributes. e.g.,

__getitem__方法的帮助下,用户可以访问索引属性。例如,

print p[0].name # print first (or last) name
print p[Y].dob  # print (Date or Month or ) Year of the 'date of birth'