__getitem__
относится к способам получения элементов экземпляров класса, в котором он определен.
Итак, если вы определите __getitem__
в метаклассе, он будет работать для классов - если вы напишите __getitem__
в самом классе, он будет работать только для экземпляров этого класса.
Однако вы можете написать метакласс __getitem__
, чтобы он вызывал класс '__getitem__
, если он существует - и затем эмулировать это поведение:
class MyMetaclass(type):
def __new__(cls, name, bases, attrs):
attrs.update({'_my_dict': {'key1': 'value1', 'key2': 'value2'}})
return super().__new__(cls, name, bases, attrs)
def __getitem__(cls, value):
for supercls in cls.__mro__:
if "__getitem__" in supercls.__dict__:
# getting the value straight from "__dict__" will prevent Python's mechanisms of converting it to a bound instance method:
return supercls.__dict__["__getitem__"](cls, value)
return cls._my_dict[str(value)]
class MyBaseClass(metaclass=MyMetaclass):
pass
class MyClass(MyBaseClass):
def __getitem__(cls, value):
return 'overridden'
Обратите внимание, что таким образом, вы можете даже использовать любое другое имя метода для "class_getitem" в нашей иерархии и при этом оставить обычное __getitem__
доступно для использования экземплярами.