sktime.registry._craft 源代码
# copyright: sktime developers, BSD-3-Clause License (see LICENSE file)
"""Quick crafting methods to build an object from string and registry.
craft(spec)
craft an object or estimator from string
deps(spec)
retrieves all dependencies required to craft str, in PEP440 format
The ``craft`` function is a pair to ``str`` coercion, the two can be seen as
deserialization/serialization counterparts to each other.
That is,
spec = str(my_est)
new_est = craft(spec)
will have the same effect as new_est = spec.clone()
"""
__author__ = ["fkiraly"]
import re
from sktime.registry._lookup import all_estimators
def _extract_class_names(spec):
"""Get all maximal alphanumeric substrings that start with a capital letter.
Parameters
----------
spec : str (any)
Returns
-------
cls_name_list : list of str
list of all maximal alphanumeric substrings starting with a capital in ``spec``
excluding reserved expressions True, False (if they occur)
"""
# class names are all UpperCamelCase alphanumeric strings
# which is the same as maximal substrings starting with a capital
pattern = r"\b([A-Z][A-Za-z0-9_]*)\b"
cls_name_list = re.findall(pattern, spec)
# we need to exclude expressions that look like classes per the regex
# but aren't
EXCLUDE_LIST = ["True", "False"]
cls_name_list = [x for x in cls_name_list if x not in EXCLUDE_LIST]
return cls_name_list
[文档]def craft(spec):
"""Instantiate an object from the specification string.
Parameters
----------
spec : str, sktime/skbase compatible object specification
i.e., a string that executes to construct an object if all imports were present
imports inferred are of any classes in the scope of ``all_estimators``
option 1: a string that evaluates to an estimator
option 2: a sequence of assignments in valid python code,
with the object to be defined preceded by a "return"
assignments can use names of classes as if all imports were present
Returns
-------
obj : skbase BaseObject descendant, constructed from ``spec``
this will have the property that ``spec == str(obj)`` (up to formatting)
"""
register = dict(all_estimators()) # noqa: F841
for x in _extract_class_names(spec):
exec(f"{x} = register['{x}']")
try:
obj = eval(spec)
except Exception:
from textwrap import indent
spec_fun = indent(spec, " ")
spec_fun = (
"""
def build_obj():
"""
+ spec_fun
)
exec(spec_fun, locals())
obj = eval("build_obj()")
return obj
[文档]def deps(spec):
"""Get PEP 440 dependency requirements for a craft spec.
Parameters
----------
spec : str, sktime/skbase compatible object specification
i.e., a string that executes to construct an object if all imports were present
imports inferred are of any classes in the scope of ``all_estimators``
option 1: a string that evaluates to an estimator
option 2: a sequence of assignments in valid python code,
with the object to be defined preceded by a "return"
assignments can use names of classes as if all imports were present
Returns
-------
reqs : list of str
each str is PEP 440 compatible requirement string for craft(spec)
if spec has no requirements, return is [], the length 0 list
"""
register = dict(all_estimators())
dep_strs = []
for x in _extract_class_names(spec):
if x not in register.keys():
raise RuntimeError(
f"class {x} is required to build spec, but was not found "
"in all_estimators scope"
)
cls = register[x]
new_deps = cls.get_class_tag("python_dependencies")
if isinstance(new_deps, list):
dep_strs += new_deps
elif isinstance(new_deps, str) and len(new_deps) > 0:
dep_strs += [new_deps]
reqs = list(set(dep_strs))
return reqs
[文档]def imports(spec):
"""Get import code block for a craft spec.
Parameters
----------
spec : str, sktime/skbase compatible object specification
i.e., a string that executes to construct an object if all imports were present
imports inferred are of any classes in the scope of ``all_estimators``
option 1: a string that evaluates to an estimator
option 2: a sequence of assignments in valid python code,
with the object to be defined preceded by a "return"
assignments can use names of classes as if all imports were present
Returns
-------
import_str : str
python code consisting of all import statements required for spec
imports cover object/estimator classes found as sub-strings of spec
"""
register = dict(all_estimators())
import_strs = []
for x in _extract_class_names(spec):
if x not in register.keys():
raise RuntimeError(
f"class {x} is required to build spec, but was not found "
"in all_estimators scope"
)
cls = register[x]
import_str = f"from {cls.__module__} import {x}"
import_strs += [import_str]
if len(import_strs) == 0:
imports_str = ""
else:
imports_str = "\n".join(sorted(import_strs))
return imports_str