allennlp.common.registrable.Registrable is a "mixin" for endowing
any base class with a named registry for its subclasses and a decorator
for registering them.
Any class that inherits from
Registrable gains access to a named registry for its
subclasses. To register them, just decorate them with the classmethod
After which you can call
BaseClass.list_available() to get the keys for the
registered subclasses, and
BaseClass.by_name(name) to get the corresponding subclass.
Note that the registry stores the subclasses themselves; not class instances.
In most cases you would then call
from_params(params) on the returned subclass.
You can specify a default by setting
If it is set, it will be the first element of
Note that if you use this class to implement a new
Registrable abstract class,
you must ensure that all subclasses of the abstract class are loaded when the module is
loaded, because the subclasses register themselves in their respective files. You can
achieve this by having the abstract class and all subclasses in the init.py of the
module in which they reside (as this causes any import of either the abstract class or
a subclass to load all other subclasses and the abstract class).
class Registrable(FromParams): | ... | default_implementation: Optional[str] = None
class Registrable(FromParams): | ... | @classmethod | def register( | cls, | name: str, | constructor: Optional[str] = None, | exist_ok: bool = False | ) -> Callable[[Type[_T]], Type[_T]]
Register a class under a particular name.
- name :
The name to register the class under.
- constructor :
str, optional (default =
The name of the method to use on the class to construct the object. If this is given, we will use this method (which must be a
@classmethod) instead of the default constructor.
- exist_ok :
bool, optional (default =
If True, overwrites any existing models registered under
name. Else, throws an error if a model is already registered under
To use this class, you would typically have a base class that inherits from
class Vocabulary(Registrable): ...
Then, if you want to register a subclass, you decorate it like this:
@Vocabulary.register("my-vocabulary") class MyVocabulary(Vocabulary): def __init__(self, param1: int, param2: str): ...
Registering a class like this will let you instantiate a class from a config file, where you
"type": "my-vocabulary", and keys corresponding to the parameters of the
method (note that for this to work, those parameters must have type annotations).
If you want to have the instantiation from a config file call a method other than the
constructor, either because you have several different construction paths that could be
taken for the same object (as we do in
Vocabulary) or because you have logic you want to
happen before you get to the constructor (as we do in
Embedding), you can register a
@classmethod as the constructor to use, like this:
@Vocabulary.register("my-vocabulary-from-instances", constructor="from_instances") @Vocabulary.register("my-vocabulary-from-files", constructor="from_files") class MyVocabulary(Vocabulary): def __init__(self, some_params): ... @classmethod def from_instances(cls, some_other_params) -> MyVocabulary: ... # construct some_params from instances return cls(some_params) @classmethod def from_files(cls, still_other_params) -> MyVocabulary: ... # construct some_params from files return cls(some_params)
class Registrable(FromParams): | ... | @classmethod | def by_name( | cls: Type[_RegistrableT], | name: str | ) -> Callable[..., _RegistrableT]
Returns a callable function that constructs an argument of the registered class. Because
you can register particular functions as constructors for specific names, this isn't
__init__ method of some class.
class Registrable(FromParams): | ... | @classmethod | def resolve_class_name( | cls: Type[_RegistrableT], | name: str | ) -> Tuple[Type[_RegistrableT], Optional[str]]
Returns the subclass that corresponds to the given
name, along with the name of the
method that was registered as a constructor for that
name, if any.
This method also allows
name to be a fully-specified module name, instead of a name that
was already added to the
Registry. In that case, you cannot use a separate function as
a constructor (as you need to call
cls.register() in order to tell us what separate
function to use).
class Registrable(FromParams): | ... | @classmethod | def list_available(cls) -> List[str]
List default first if it exists