【发布时间】:2021-09-21 13:07:25
【问题描述】:
x[i]大致相当于type(x).__getitem__(x, i)。
与拥有看似简单的x.__getitem__(i)相比,上述方法有什么好处?
编辑:为什么 Python 会这样?
作为标准行为的一个缺点,让我展示这个示例代码,我惊讶地发现最后一个断言失败,而倒数第二个断言(直接调用 __getitem__)通过了。
def poww_bar(base):
class Bar():
def __getitem__(self, x):
return lambda: base**x
return Bar()
def poww_foo(base):
class Foo():
pass
f = Foo()
f.__getitem__ = lambda x: lambda: base ** x
return f
pow_bar2 = poww_bar(2)
pow_foo2 = poww_foo(2)
assert pow_bar2.__getitem__(3)() == 8 # OK
assert pow_bar2[3]() == 8 # OK
assert pow_foo2.__getitem__(3)() == 8 # OK
assert pow_foo2[3]() == 8 # TypeError: 'Foo' object is not subscriptable
【问题讨论】:
-
它失败可能是因为定义索引运算符不仅仅是
f.__getitem__ = ...。也许当你做def __getitem__(...): ...时,解释器会在幕后做一些魔术来将此函数注册为特殊的并且有资格使用索引语法糖 -
此外,您的
f.__getitem__版本仅属于Foo的单个实例f,而不是整个类(它接受1 个参数,与标准版本中的(self, x)相比) -
@AlexeyLarionov 似乎 OP 意识到了这一点,并在问 为什么 Python 会这样。
标签: python magic-methods syntactic-sugar