lga*_*ier 6 python single-dispatch
有没有办法“取消注册”泛型的注册函数?
例如:
from functools import singledispatch
@singledispatch
def foo(x):
return 'default function'
foo.register(int, lambda x: 'function for int')
# later I would like to revert this.
foo.unregister(int) # does not exist - this is the functionality I am after
Run Code Online (Sandbox Code Playgroud)
singledispatch仅用于附加;你不能真正注销任何东西。
但是与 Python 的所有事物一样,实现可以被强制取消注册。以下函数将向unregister()singledispatch 函数添加一个方法:
def add_unregister(func):
# build a dictionary mapping names to closure cells
closure = dict(zip(func.register.__code__.co_freevars,
func.register.__closure__))
registry = closure['registry'].cell_contents
dispatch_cache = closure['dispatch_cache'].cell_contents
def unregister(cls):
del registry[cls]
dispatch_cache.clear()
func.unregister = unregister
return func
Run Code Online (Sandbox Code Playgroud)
这进入singledispatch.register()函数的闭包以访问实际registry字典,因此我们可以删除已注册的现有类。我还清除了dispatch_cache弱参考字典以防止它介入。
您可以将其用作装饰器:
@add_unregister
@singledispatch
def foo(x):
return 'default function'
Run Code Online (Sandbox Code Playgroud)
演示:
>>> @add_unregister
... @singledispatch
... def foo(x):
... return 'default function'
...
>>> foo.register(int, lambda x: 'function for int')
<function <lambda> at 0x10bed6400>
>>> foo.registry
mappingproxy({<class 'object'>: <function foo at 0x10bed6510>, <class 'int'>: <function <lambda> at 0x10bed6400>})
>>> foo(1)
'function for int'
>>> foo.unregister(int)
>>> foo.registry
mappingproxy({<class 'object'>: <function foo at 0x10bed6510>})
>>> foo(1)
'default function'
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
295 次 |
| 最近记录: |