包装对象以使包装器__call__调用包装的对象__getitem__方法的最简单方法是什么

时间:2019-05-18 02:01:11

标签: python python-3.x wrapper

请考虑以下代码段:

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 个答案:

答案 0 :(得分:5)

简单的情况就是简单地实现一个基本的包装器类,该类以这些术语定义__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__')

此处未对最终可调用对象进行任何实际定义,您只是绑定现有方法并返回它。