Python-可扩展性方案,register使用

  • Post author:
  • Post category:python




文档

官方:

教程:

基础: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)。分两步:

  1. register_obj.register(“model_one”),词是target为”model_one”,所以返回lambda x: add(“model_one”, x)
  2. lambda x :add(“model_one”, x) 参数为(Model1),则最终执行add(“model_one”, Model_1)



版权声明:本文为Code_LT原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。