У меня есть подкласс байтов, который предоставляет метод dunk . Метод __getitem__
всегда вызывается в Python 3.5, но вызывается только для нерезких ключей в Python 2.7. (Вместо этого, похоже, что к экземпляру применяется __getitem__
родителя.) Почему это и есть обходной путь?Почему __getitem__ вызывается в Python 3.5, но не в Python 2.7?
Код
class A(object):
def __getitem__(self, key):
print("in A.__getitem__ with key " + str(key))
return []
class B(bytes):
def __getitem__(self, key):
print("in B.__getitem__ with key " + str(key))
return []
if __name__ == "__main__":
import sys
print(sys.version)
a = A()
b = B()
print("[0]")
a[0]
b[0]
print("[0:1]")
a[0:1]
b[0:1]
print("[:1]")
a[:1]
b[:1]
Python 3.5 Выход
Класс определенный __getitem__
всегда называется.
(venv) snafu$ python ./x.py
3.5.2 (default, Nov 17 2016, 17:05:23)
[GCC 5.4.0 20160609]
[0]
in A.__getitem__ with key 0
in B.__getitem__ with key 0
[0:1]
in A.__getitem__ with key slice(0, 1, None)
in B.__getitem__ with key slice(0, 1, None)
[:1]
in A.__getitem__ with key slice(None, 1, None)
in B.__getitem__ with key slice(None, 1, None)
Python 2.7 Выход
Класс определенный __getitem__
вызывается только для ключей без среза.
(venv2.7) snafu$ python x.py
2.7.12 (default, Nov 19 2016, 06:48:10)
[GCC 5.4.0 20160609]
[0]
in A.__getitem__ with key 0
in B.__getitem__ with key 0
[0:1]
in A.__getitem__ with key slice(0, 1, None)
[:1]
in A.__getitem__ with key slice(None, 1, None)
Doh! Это даже странно: вызов '__getitem__' с явными срезами (например,' b [slice (0,1, None)] ') * работает * на обоих Python 2.7 и 3.5. Похоже, что в Python 2.7 запись 'b [s: e]' is * not * совпадает с буквой 'b [slice (s, e)]', когда b является подклассом встроенного типа. – Reece