我有一个带有三个注册函数的method dispatch decorator。一个是在int
上发送,这很好。第二个在自定义类型上调度,也可以正常工作。第三个也是自定义类型,但是类是用lru_cache
装饰器包装的。你知道吗
(为了使事情更复杂一些,该类通过另一个类的__call__
方法上的methoddispatch以迂回的方式实例化。)
@lru_cache(maxsize=None, typed=True)
class QualifiedInterval:
# stuff that works
在球场内:
@oph_utils.method_dispatch
def augmented(self, other):
raise NotImplementedError
@augmented.register(int)
def _(self, other):
return "works fine"
@augmented.register(Interval)
def _(self, other):
return "works fine too"
@augmented.register(QualifiedInterval)
def _(self, other):
return "only works if QualifiedInterval class does NOT have lru_cache"
(还有很多事情要做,但这些都不管用。)
基本上-如果我有lru\u缓存,并将一个限定的interval传递到函数中,它不会分派并引发NotImplementedError。如果我注释掉缓存装饰器,它就工作了。REPL的手动类型检查显示了相同的类型(“QualifiedInterval”)。我试着用几种不同的方法调用创建QualifiedInterval的命令,并试着将它赋给一个变量。还是不行。我试过在增广函数中做显式类型检查。如果启用了缓存,类型检查也会失败。你知道吗
分析出了什么问题
lru_cache是返回一个decorator的函数,它包装了任何可调用的(包括类)。因此,当您将lru\u缓存应用于QualifiedInterval类时,该变量将被分配给包装函数,而不是类本身。你知道吗
Single dispatch通过将第一个参数的类型匹配到适当的方法来工作。但是,当您传入一个QualifiedInterval的实例时,它的类型与functools.\u lru\u cache\u wrapper不匹配,因此单次分派会返回到基方法(它会引发NotImplemented)。你知道吗
解决方案
教单个分派匹配实际的原始类(类型),而不是包装类:
注意添加了
.__wrapped__
属性,该属性通过包装函数到达原始的unwrapped类。你知道吗希望这一切都能澄清,并指明前进的方向:-)
相关问题 更多 >
编程相关推荐