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

Too*_*one 2 python wrapper python-3.x

考虑以下代码片段:

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

kal = wrap(dikt)

assert(kal("City") == dikt["City"])
assert(kal("State") == dikt["State"])
Run Code Online (Sandbox Code Playgroud)

实现该wrap功能的最简单方法是什么?我们希望包装器的__call__方法调用包装对象的__getitem__方法。

Sha*_*ger 5

就简单而言,简单就是只实现一个基本的包装器类,该类__call__用以下术语定义:

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

    def __call__(self, x):
        return self.mapping[x]
Run Code Online (Sandbox Code Playgroud)

使用闭包的函数工厂略短(至少在CPython上,调用稍快),但可配置性/可检查性/可扩展性较差:

def wrap(mapping):
    def wrapped(x):
        return mapping[x]
    return wrapped
Run Code Online (Sandbox Code Playgroud)

最后,最简单(但至少是可配置的),直接返回bound __getitem__

def wrap(mapping):
    return mapping.__getitem__
Run Code Online (Sandbox Code Playgroud)

或使用现有工具甚至将绑定推入C(无论如何在CPython上):

from operator import attrgetter

wrap = attrgetter('__getitem__')
Run Code Online (Sandbox Code Playgroud)

这里没有对final可调用对象进行任何实际定义,您只是绑定现有方法并返回它。

  • 我拒绝将其包含在答案中,因为实际上不应使用它来解决问题,但是由于包装非常简单,因此您实际上可以将工厂函数/关闭解决方案单行显示为:`wrap = lambda m :lambda x:m [x]`如果您将其用于代码打高尔夫球之外的其他事情,请期待您的开发人员将您的代码(也许您可以作好准备)付诸行动。 (3认同)