import sys
import os
import functools
import inspect
from collections import defaultdict
import json
def evaluate(filename):
with open(filename, "r") as evaluate_file:
return evaluate_file.read()
class Params(object):
DEFAULT = object()
def __init__(self, params):
self.params = params
def __setitem__(self, key, value):
self.params[key] = value
def __getitem__(self, item):
return self.params[item]
@classmethod
def from_file(cls, params_file):
file_dict = json.loads(evaluate(params_file))
return cls(file_dict)
@classmethod
def from_args(cls, args):
file_dict = json.loads(args)
return cls(file_dict)
def pop(self, key, default=DEFAULT):
if default is self.DEFAULT:
try:
value = self.params.pop(key)
except KeyError:
msg = "key {} is required".format(key)
raise ConfigurationError(msg)
else:
value = self.params.pop(key, default)
return value
def is_base_registrable(cls):
if not issubclass(cls, Register):
return False
method_resolution_order = inspect.getmro(cls)[1:]
for base_class in method_resolution_order:
if issubclass(base_class, Register) and base_class is not Register:
return False
return True
class FromParams(object):
@classmethod
def from_params(cls, params):
registered_class = Register._registry.get(cls)
if is_base_registrable(cls) and registered_class is None:
raise ConfigurationError("tried to construct and abstract Registrable base class that has no registered")
if registered_class is not None:
choice = params.pop("type")
subclass, constructor_name = cls.resolve_class_name(choice)
args = params.pop("params")
return subclass(args)
return None
class ConfigurationError(Exception):
def __init__(self, message):
super(ConfigurationError, self).__init__()
self.message = message
def __str__(self):
return self.message
class Register(FromParams):
_registry = defaultdict(dict)
@classmethod
def register(cls, name, constructor=None, exist_ok=False):
print("cls:", cls)
registry = Register._registry[cls]
def add_sbuclass_to_registry(subclass):
print("sub class:", subclass)
if name in registry:
if exist_ok:
message = ("{} has already been registered as {}, but exist_ok=True, so overwriting with {}".format(name,
registry[
name][
0].__name__,
cls.__name__))
print(message)
else:
message = (
"Cannot register {} as {}; name already in use for {}".format(name, cls.__name__,
registry[name][0].__name__)
)
raise ConfigurationError(message)
registry[name] = (subclass, constructor)
return subclass
return add_sbuclass_to_registry
@classmethod
def resolve_class_name(cls, name):
if name in Register._registry[cls]:
subclass, constructor = Register._registry[cls].get(name)
return subclass, constructor
else:
# is not a qualified class name
raise ConfigurationError(
"{} is not a registered name for {}. ".format(name, cls.__name__)
)
class Model(Register):
def __init__(self, params):
print("Model init params:",params)
@Model.register("IrisModel")
class IrisModel(Model):
def __init__(self, params):
super(IrisModel, self).__init__(params)
print("IrisModel Init")
json_conf = '''
{"type" : "IrisModel",
"params" : {
"name" : "like",
"reader" : "reader"
}
}
'''
params = Params.from_args(json_conf)
model = Model.from_params(params)
python class 装饰器
最新推荐文章于 2024-08-30 11:16:31 发布