文档
官方:
教程:
基础:https://applenob.github.io/python/register/
简单示例:https://www.jianshu.com/p/8b2c915dc39f
深度学习种使用注册器:https://zhuanlan.zhihu.com/p/350787676
笔记
#使用注册器
if __name__ == "__main__":
register_obj = RegisterMachine("register")
# decorate method
@register_obj.register()
def say_hello_with(name):
print("Hello, {person}!".format(person=name))
@register_obj.register()
def say_hi_with(name):
print("Hi, {person}!".format(person=name))
register_obj.get("say_hello_with")("Peter")
# function call method
register_obj.register(say_hi_with)
register_obj.get("say_hi_with")("John")
注释器实际上是用了python的装饰器特性,创建了一个可扩展的register_obj 对象,对象种维护了一个可扩展的字典,字典中是我们想存储的 name->obj,可能是:
name->函数
name->类
name->类实例
解惑
要注册的模块
class Model:
pass
@Registers.model.register
class Model1(Model):
pass
@Registers.model.register
class Model2(Model):
pass
@Registers.model.register
class Model3(Model):
pass
注册器 Register
class Register:
def __init__(self, registry_name):
self._dict = {}
self._name = registry_name
def __setitem__(self, key, value):
if not callable(value):
raise Exception(f"Value of a Registry must be a callable!\nValue: {value}")
if key is None:
key = value.__name__
if key in self._dict:
logging.warning("Key %s already in registry %s." % (key, self._name))
self._dict[key] = value
def register(self, target):
"""Decorator to register a function or class."""
def add(key, value):
self[key] = value
return value
if callable(target):
# @reg.register
return add(None, target)
# @reg.register('alias')
return lambda x: add(target, x)
def __getitem__(self, key):
return self._dict[key]
def __contains__(self, key):
return key in self._dict
def keys(self):
"""key"""
return self._dict.keys()
@register_obj.register
class Modle1:
等价于register_obj.register(Model1),最终执行的是add(None, Model1)。
而:
@register_obj.register("model_one")
class Model1:
实际上是register_obj.register(“model_one”)(Model1),最终执行的是add(“model_one”, Model_1)。
为何??
callable() 函数用于检查一个对象是否是可调用的。如果返回 True,object 仍然可能调用失败;但如果返回 False,调用对象 object 绝对不会成功。
对于函数、方法、lambda 函式、 类以及实现了 __call__
方法的类实例, 它都返回 True。
@decorate
def func():
# 等价于func = decorate(func)
register_obj.register(Model1),最终执行的是add(None, Model1)好理解。
register_obj.register(“model_one”)(Model1),最终执行的是add(“model_one”, Model_1)。分两步:
- register_obj.register(“model_one”),词是target为"model_one",所以返回lambda x: add(“model_one”, x)
- lambda x :add(“model_one”, x) 参数为(Model1),则最终执行add(“model_one”, Model_1)