使用唯一的键值(keys)来标记各种信息
用于注册各种不同的类(class)
from mmf.common.registry import registry
Register a trainer:
@registry.register_trainer
Register a dataset builder:
@registry.register_builder
Register a metric:
@registry.register_metric
Register a loss:
@registry.register_loss
Register a fusion technique:
@registery.register_fusion
class Registry:
mapping = {
# 使用 `registry.register_builder` 注册添加一个新的生成器类 (builder),其他部件(trainer/...)同理
#mapping字典存放了各个部件对应的所有被创建的类
"builder_name_mapping": {},
"trainer_name_mapping": {},
"model_name_mapping": {},
"metric_name_mapping": {},
"loss_name_mapping": {},
"fusion_name_mapping": {},
"optimizer_name_mapping": {},
"scheduler_name_mapping": {},
"processor_name_mapping": {},
"encoder_name_mapping": {},
"decoder_name_mapping": {},
"transformer_backend_name_mapping": {},
"state": {},
}
@classmethod
def register_trainer(cls, name):
#以name为key的trainer将被注册
"""
用法
from mmf.common.registry import registry
from mmf.trainers.custom_trainer import CustomTrainer
@registry.register_trainer("custom_trainer")
class CustomTrainer():
...
即trainer_name_mapping中添加了custom_trainer类
"""
def wrap(trainer_cls):
cls.mapping["trainer_name_mapping"][name] = trainer_cls
return trainer_cls
return wrap
作用
classmethod对应的函数不需要实例化,不需要self参数
但是第一个参数需要的是自身类的cls参数
返回值
返回函数的类方法
举例
class A(object):
bar = 1
def func1(self):
print ('foo')
@classmethod
def func2(cls):
print ('func2')
print (cls.bar)
cls().func1() # 调用 foo 方法
A.func2() # 不需要实例化
作用
通过装饰器函数在不修改原函数的前提下,对函数的功能进行合理扩充
举例
#funA 作为装饰器函数
def funA(fn):
#...
fn() # 执行传入的fn参数
#...
return '...'
@funA
def funB():
#...
等价于
def funA(fn):
#...
fn() # 执行传入的fn参数
#...
return '...'
def funB():
#...
funB = funA(funB)
以上执行的操作为两步:
注意被“@函数”修饰的函数不再是原来的函数,取决于返回值
如果装饰器函数返回值是普通变量,那么被就是的函数名就变成了普通变量,如果装饰器函数返回的是一个函数的名称,那么被修饰的函数名仍然是一个函数