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
これは関数のクロージャに到達してsingledispatch.register()
実際のregistry
辞書にアクセスし、登録された既存のクラスを削除できるようにします。dispatch_cache
また、弱参照辞書が介入しないようにクリアします。
これをデコレータとして使用できます。
@add_unregister
@singledispatch
def foo(x):
return 'default function'
デモ:
>>> @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'