注销singledispatch?

2024-10-05 14:26:40 发布

您现在位置:Python中文网/ 问答频道 /正文

有没有办法“注销”泛型的已注册函数?在

例如:

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

Tags: 函数fromimportregisterdefaultreturnfoodef
1条回答
网友
1楼 · 发布于 2024-10-05 14:26:40

singledispatch只能追加;您不能真正注销任何内容。在

但与Python的所有东西一样,实现可能会被迫注销。以下函数将向单个分派函数添加unregister()方法:

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

这涉及到singledispatch.register()函数的闭包,以访问实际的registry字典,这样我们就可以删除已注册的现有类。我还清除了dispatch_cache弱引用字典,以防止它介入。在

您可以将其用作装饰:

^{pr2}$

演示:

>>> @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'

相关问题 更多 >