python 的 register 类可以理解为一个字典,这个字典里边会存储很多相同系列的类。
注册器也可以让工程扩展性变好,当需要增加新类的时候,可以复用之前的逻辑,只需要给注册器这个字典里边添加即可。
以 mmdet 为例,mmdet/models/registry.py
代码如下:
# mmdet.utils 的 Registry 中实现了注册器类
from mmdet.utils import Registry
# 这里都是对注册器类的实例化,传入的是一个字符串,这个字符串是name属性
# 注册了一个对象名为 BACKBONES,属性名为 backbone 的对象
BACKBONES = Registry('backbone')
NECKS = Registry('neck')
ROI_EXTRACTORS = Registry('roi_extractor')
SHARED_HEADS = Registry('shared_head')
HEADS = Registry('head')
LOSSES = Registry('loss')
DETECTORS = Registry('detector')
简单例子:
class RegisterMachine(object):
def __init__(self, name):
# name of register
self._name = name
self._name_method_map = dict()
def register(self, obj=None):
# obj == None for function call register
# otherwise for decorator way
if obj != None:
name = obj.__name__
self._name_method_map[name] = obj
else:
def wrapper(func):
name = func.__name__
self._name_method_map[name] = func
return func
return wrapper
def get(self, name):
return self._name_method_map[name]
if __name__ == "__main__":
register_obj = RegisterMachine("register") # <__main__.RegisterMachine object at 0x7fa5d8aaba00>
# register_obj._name = 'register'
# register_obj._name_method_map = {}
# decorate method
@register_obj.register()
def say_hello_with(name):
print("Hello, {person}!".format(person=name))
def say_hi_with(name):
print("Hi, {person}!".format(person=name))
register_obj.get("say_hello_with")("Peter") # output: Hello, Peter!
# 这个时候的 register_obj:
# {
# 'say_hello_with':
# }
register_obj.register(say_hi_with) # output: None
# 这个时候的 register_obj:
# {
# 'say_hello_with': ,
# 'say_hi_with':
# }
register_obj.get("say_hi_with")("John") # output: Hi, John!
# 这个时候的 register_obj:
# {
# 'say_hello_with': ,
# 'say_hi_with':
# }
register_obj.get("say_hello_with")("Peter") # get → register → say_hello_with
register_obj.get("say_hi_with")("John") # get → say_hi_with