#python #python-3.x
Вопрос:
Итак, я хочу реализовать класс, содержащий вложенные данные. Я хотел бы реализовать __getitem__
таким образом, чтобы это obj[x][y]
можно было сократить obj[x, y]
.
Однако я заметил проблему: сигнатура __getitem__
заключается в том, что вместо этого он ожидает один позиционный аргумент *args
. Если задано несколько аргументов, они автоматически помещаются в кортеж.
Т. е. obj[a, b]
и obj[(a, b)]
то и другое, по-видимому, эквивалентно obj.__getitem__((a,b))
Но тогда как я могу отличить эти два случая
- Внешний слой индексируется кортежами и
obj[(a, b)]
должен возвращать значение по этому индексу - Внешний слой не индексируется кортежами и
obj[a, b]
должен возвращатьobj[a][b]
Единственными возможными решениями, о которых я знаю в настоящее время, являются
- Откажитесь от идеи принуждения
obj[x, y]
кobj[x][y]
- Если мы только хотим
obj[x]
всегда писатьobj[x,]
вместо этого.
И то, и другое на самом деле не является удовлетворительным.
Комментарии:
1. Это
isinstance
правильный путь ?2. @KrisI думал об этом, но, похоже, будет нелегко, если код не будет зависеть от того, какие объекты используются для индексирования внешнего/внутреннего слоя.
3.
obj[(a, b),]
?4. @iacob это именно то решение (2), которое я излагаю в посте, но я не нахожу его удовлетворительным и предпочел бы отказаться
obj[x,y]
, если нет лучшей альтернативы.
Ответ №1:
За исключением попыток проверить исходный код вызова (который чрезвычайно хрупок, со всевозможными случаями сбоев, которые и близко не стоят нестабильности и головной боли при отладке), это невозможно.
obj[a, b]
и obj[(a, b)]
означают точно то же самое в Python. Нет никакой семантической разницы, никакой разницы в том, как они выполняются, и нет ничего, за что можно было бы зацепиться, чтобы отличить их. Это было бы все равно, что пытаться различить пробелы в obj[a,b]
и obj[a, b]
.
Комментарии:
1. Это действительно прискорбно. Интересно, почему python, по крайней мере, не допускает пользовательскую реализацию
__getitem__
с подписью__getitem__(self, *items)
вместо__getitem__(self, item)
2. @Hyperplane: Есть множество вещей, которые команда разработчиков могла бы сделать
__getitem__
, например, разрешить аргументы ключевых слов иobj[x=y]
… но эти вещи не дают достаточной пользы в конкретных случаях использования, чтобы оправдать дополнительную сложность. (Они могут принести некоторую пользу, но не настолько , чтобы стоило усложнять язык.)