什么是 Register
# 什么是 Register
# 01、Register 的核心是装饰器
@ 是 python 的装饰语法糖
@decorate
def func():
1
2
2
等价于:
func = decorate(func)
1
# 02、mmcv 中 Registry
类的实现
# 2.1 核心逻辑
class Registry:
def __init__(self, name):
# 可实现注册类细分功能
self._name = name
# 内部核心内容,维护所有的已经注册好的 class
self._module_dict = dict()
def _register_module(self, module_class, module_name=None, force=False):
if not inspect.isclass(module_class):
raise TypeError('module must be a class, '
f'but got {type(module_class)}')
if module_name is None:
module_name = module_class.__name__
if not force and module_name in self._module_dict:
raise KeyError(f'{module_name} is already registered '
f'in {self.name}')
# 最核心代码
self._module_dict[module_name] = module_class
# 装饰器函数
def register_module(self, name=None, force=False, module=None):
if module is not None:
# 如果已经是 module,那就知道 增加到字典中即可
self._register_module(
module_class=module, module_name=name, force=force)
return module
# 最标准用法
# use it as a decorator: @x.register_module()
def _register(cls):
self._register_module(
module_class=cls, module_name=name, force=force)
return cls
return _register
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# 2.2 类实例化
在 MMCV 中所有的类实例化都是通过 build_from_cfg
函数实现,做的事情非常简单,就是给定 module_name
,然后从 self._module_dict
提取即可。
def build_from_cfg(cfg, registry, default_args=None):
args = cfg.copy()
if default_args is not None:
for name, value in default_args.items():
args.setdefault(name, value)
obj_type = args.pop('type') # 注册 str 类名
if is_str(obj_type):
# 相当于 self._module_dict[obj_type]
obj_cls = registry.get(obj_type)
if obj_cls is None:
raise KeyError(
f'{obj_type} is not in the {registry.name} registry')
# 如果已经实例化了,那就直接返回
elif inspect.isclass(obj_type):
obj_cls = obj_type
else:
raise TypeError(
f'type must be a str or valid type, but got {type(obj_type)}')
# 最终初始化对于类,并且返回,就完成了一个类的实例化过程
return obj_cls(**args)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 2.3 完整的使用例子
- 先创建一个 Register
- 然后注册一个 module
- 然后根据 cfg 以及 Register 调用
CONVERTERS = Registry('converter')
@CONVERTERS.register_module()
class Converter1(object):
def __init__(self, a, b):
self.a = a
self.b = b
converter_cfg = dict(type='Converter1', a=a_value, b=b_value)
converter = build_from_cfg(converter_cfg,CONVERTERS)
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
上次更新: 2021/08/02, 21:04:52
- 02
- README 美化05-20
- 03
- 常见 Tricks 代码片段05-12