Какой самый простой способ обернуть объект таким образом, что оболочка __call__ вызывает метод обернутых объектов __getitem__ - PullRequest
2 голосов
/ 18 мая 2019

Рассмотрим следующий фрагмент кода:

dikt =  {
  "City": "Denver",
  "State": "Colorado",
  "Street": "123 Nowhere St."
}

kal = wrap(dikt)

assert(kal("City") == dikt["City"])
assert(kal("State") == dikt["State"])

Какой самый простой способ реализовать функцию wrap?Мы хотим, чтобы метод __call__ обертки вызывал метод обернутых объектов __getitem__.

1 Ответ

5 голосов
/ 18 мая 2019

Простым в случае простого является просто реализовать базовый класс-обертку, который определяет __call__ в таких терминах:

class wrap:
    def __init__(self, mapping):
       self.mapping = mapping

    def __call__(self, x):
        return self.mapping[x]

Немного короче (и, по крайней мере, на CPython, чуть быстрее вызывать),но менее конфигурируемым / проверяемым / расширяемым является фабрика функций, использующая замыкания:

def wrap(mapping):
    def wrapped(x):
        return mapping[x]
    return wrapped

Наконец, и наиболее просто (но наименее конфигурируемо), есть прямой возврат границы __getitem__:

def wrap(mapping):
    return mapping.__getitem__

или используя существующие инструменты для принудительной привязки даже к C (в любом случае на CPython):

from operator import attrgetter

wrap = attrgetter('__getitem__')

Здесь не дано никакого фактического определения окончательного вызова, вы просто привязываете существующий метод и возвращаетеэто.

...