Python索引特殊方法

Python索引特殊方法,python,magic-methods,Python,Magic Methods,当通过列表而不是dict访问时,thing如何知道将自己表示为1?这两种神奇的方法不是都经过\uuu getitem\uu?列表显示的用法可以通过\uuuuu int\uuuu来代替,那么\uuu index\uuuuu的存在理由是什么呢?Dict和List的实现方式不同。Dict objects使用对象的\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu散列上的比较(\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

当通过列表而不是dict访问时,
thing
如何知道将自己表示为1?这两种神奇的方法不是都经过
\uuu getitem\uu
?列表显示的用法可以通过
\uuuuu int\uuuu
来代替,那么
\uuu index\uuuuu
的存在理由是什么呢?

Dict和List的实现方式不同。Dict objects使用对象的
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu散列
上的比较(
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu


要使
东西
可用于dict,您必须同时实现hash和eq。

@Benoîtlatiner说得对:


Dict和List的实现方式不同

不过,我想补充一点信息。根据报告:

object.\uuuuu索引\uuuuuu(self)

调用以实现
operator.index()
,并且每当Python需要无损地将数值对象转换为整数对象时(,例如 在切片中,或在内置的
bin()
hex()
oct()
功能)。此方法的存在表示数值对象 是一个整数类型。必须返回一个整数

我加粗的部分很重要。列表上的索引和切片都是通过相同的方法处理的(即,
\uuu getitem\uuu
)。因此,如果
Thing.\uuuuu index\uuuuu
被调用用于切片,它也将被调用用于索引,因为我们使用相同的方法。这意味着:

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

list_[thing]
但是,对于字典,
Thing.\uuuuuu index\uuuuu
没有被调用(没有理由调用它,因为您无法对字典进行切片)。相反,执行
dict[thing]
是告诉Python在字典中找到一个键,即
thing
实例本身。由于这不存在,因此会引发一个
KeyError

也许示范会有所帮助:

list_[thing.__index__()]
>>类事物(对象):
...     定义索引(自):
...         打印'\uuuu索引'\uuuu'调用!'
...         返回1
...
>>>东西
>>>列表\=['abc','def','ghi']
>>>调用列表[事物]#uuu索引
__索引被调用!
“def”
>>>
>>>格言={1:'马铃薯'}
>>>dict_uuu[thing]35; uuu索引_uuu不被调用
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
关键错误:
>>>
>>>如果事物是一把钥匙,那么dict#={thing:'potato'}就起作用
>>>口述[事物]
“土豆”
>>>

至于为什么
\uuuuu index\uuuuu
首先存在,原因已在中详细列出。我不会在这里重复所有内容,但基本上是这样,您可以允许任意对象充当整数,这在切片以及其他一些应用程序中都是必需的。

另一个示例要进一步理解它,这里使用一个列表参数。我想把清单限制在一定的长度。现在,对于python列表,必须使用切片索引。下面的实现解决了这个问题。基本上,这里的索引用于Python列表

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

还需要记住,
imagesInOneFile
必须是整数。

对于
\uuuuu index\uuuu
方法的完整推理,您可以阅读。基本上,
将结果强制为整数类型。想象一下,如果您编写了类似于
x[3.2:5.8]
的内容。这应该会引发一个错误,在Python中确实如此。但是,如果索引逻辑使用
\uuuu int\uuuu
,它将强制切片值为
3
5
,并且代码不会引发错误。
def __index__(self):
    return 1

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