简体   繁体   English

Python __index__特殊方法

[英]Python __index__ special method

>>> class Thing(object):
...     def __index__(self):
...         return 1
... 
>>> thing = Thing()
>>> list_ = ['abc', 'def', 'ghi']
>>> list_[thing]
'def'
>>> dict_ = {1: 'potato'}
>>> dict_[thing]
# KeyError

How does thing know to represent itself as 1 when accessed by a list, but not by a dict? 当通过列表访问时, thing如何知道将自己表示为1,而不是通过字典来表示? Don't both magic methods go through __getitem__ ? 这两种魔术方法都不能通过__getitem__吗? The usage shown for lists could go through __int__ instead so what is the raison d'être for __index__ anyway? 列表显示的用法可以通过__int__代替__int__存在理由__index__

@BenoîtLatinier was correct when he said: 当他说:@BenoîtLatinier是正确的

Dict and List does not implement __getitem__ the same way. Dict和List没有以相同的方式实现__getitem__

However, I'd like to add a little more information. 但是,我想补充一点信息。 According to the documentation : 根据文件

object.__index__(self)

Called to implement operator.index() , and whenever Python needs to losslessly convert the numeric object to an integer object ( such as in slicing , or in the built-in bin() , hex() and oct() functions). 调用实现operator.index() ,并且只要Python需要无损地将数字对象转换为整数对象( 例如在切片中 ,或在内置bin()hex()oct()函数中)。 Presence of this method indicates that the numeric object is an integer type. 此方法的存在表明数字对象是整数类型。 Must return an integer. 必须返回一个整数。

The part I bolded is important. 我加粗的部分很重要。 Indexing and slicing on a list are both handled by the same method (namely, __getitem__ ). 列表上的索引和切片都由相同的方法处理(即__getitem__ )。 So, if Thing.__index__ is called for slicing, it will likewise be called for indexing since we are using the same method. 因此,如果调用Thing.__index__进行切片,则同样会调用它进行索引,因为我们使用相同的方法。 This means that: 这意味着:

list_[thing]

is roughly equivalent to: 大致相当于:

list_[thing.__index__()]

For the dictionary however, Thing.__index__ is not being called (there is no reason to call it since you cannot slice a dictionary). 然而,对于字典,没有调用Thing.__index__ (因为你不能对字典进行切片,所以没有理由调用它)。 Instead, doing dict_[thing] is telling Python to find a key in the dictionary that is the thing instance itself. 相反,做dict_[thing]告诉Python在字典中查找thing本身的一个键。 Since this doesn't exist, a KeyError is raised. 由于这不存在,因此引发了KeyError

Perhaps a demonstration will be helpful: 也许演示会有所帮助:

>>> class Thing(object):
...     def __index__(self):
...         print '__index__ called!'
...         return 1
...
>>> thing = Thing()
>>> list_ = ['abc', 'def', 'ghi']
>>> list_[thing]  # __index__ is called
__index__ called!
'def'
>>>
>>> dict_ = {1: 'potato'}
>>> dict_[thing]  # __index__ is not called
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: <__main__.Thing object at 0x01ACFC70>
>>>
>>> dict_ = {thing: 'potato'} # Works if thing is a key
>>> dict_[thing]
'potato'
>>>

As for why __index__ exists in the first place, the reason is thoroughly listed in PEP 0375 . 至于为什么__index__存在,原因在PEP 0375中彻底列出。 I won't repeat all of it here, but basically it is so that you can allow arbitrary objects to serve as integers, which is needed in slicing as well as a few other applications. 我不会在这里重复所有这些,但基本上它是这样你可以允许任意对象作为整数,这在切片以及一些其他应用程序中是必需的。

Dict and List does not implement __getitem__ the same way. Dict和List没有以相同的方式实现__getitem__ Dict objects uses a comparison ( __eq__ ) on __hash__ of objects as key to use in __getitem__ . Dict对象使用对象的__hash__上的比较( __eq__ )作为__getitem__使用的键。

To make Thing usable for dict you have to implement both hash and eq. 为了使Thing可用于dict,你必须同时实现hash和eq。

Another example to understand it further, here _MolsToGridSVG takes a list argument. 进一步理解它的另一个例子,这里_MolsToGridSVG采用list参数。 I wanted to limit the list to some length. 我想将列表限制到一定程度。 Now here for python list, slice indices have to be used. 现在这里是python列表,必须使用切片索引。 The following implementation solved it. 以下实现解决了它。 Basically here index is getting used for Python List. 基本上这里索引被用于Python List。

def __index__(self):
    return 1

imagesInOneFile = int(len(smilesMolList) / noOfFiles)
svg = Draw._MolsToGridSVG(smilesMolList[:imagesInOneFile.__index__()], subImgSize=(400, 200), molsPerRow=2)

Also one needs to remember that imagesInOneFile has to be integer. 还需要记住imagesInOneFile必须是整数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 具有__index __()方法的Python对象示例? - Examples of Python Objects That Have An __index__() method? Python - 切片索引必须是整数或无或具有 __index__ 方法 - Python - slice indices must be integers or None or have an __index__ method Python 3.5:int的子类不会调用__index__方法吗? - Python 3.5: subclasses of int don't call the __index__ method? Python __index__ 和评估顺序 - Python __index__ and evaluation order 使用 __index__ 方法进行 numpy ndarray 索引 - numpy ndarray indexing with __index__ method 不明白为什么__index__方法有效 - Not understanding why `__index__` method works Python string.find()给出错误“切片索引必须为整数或无,或具有__index__方法” - Python string.find() giving error “slice indices must be integers or None or have an __index__ method” 在 Python 中使用字符串作为切片索引? (类型错误:切片索引必须是整数或无或具有 __index__ 方法) - Use strings as slice indices in Python ? (TypeError: slice indices must be integers or None or have an __index__ method) TypeError:切片索引必须为整数或无,或具有__index__方法python - TypeError: slice indices must be integers or None or have an __index__ method python Python TypeError:切片索引必须是整数或无或具有 __index__ 方法 - Python TypeError: slice indices must be integers or None or have an __index__ method
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM