class_docstr: Defers the construction of another module until the first call.
  
  Deferred can be used to declare modules that depend on computed properties of
  other modules before those modules are defined. This allows users to separate
  the declaration and use of modules. For example at the start of your program
  you can declare two modules which are coupled:
  
      >>> encoder = snt.Linear(64)
      >>> decoder = snt.Deferred(lambda: snt.Linear(encoder.input_size))
  
  Later you can use these naturally (note: that using `decoder` first would
  cause an error since `encoder.input_size` is only defined after `encoder` has
  been called):
  
      >>> x = tf.ones([8, 32])
      >>> y = encoder(x)
      >>> z = decoder(y)  # Constructs the Linear encoder by calling the lambda.
  
  The result will satisfy the following conditions:
  
      >>> assert x.shape == z.shape
      >>> assert y.shape == [8, 64]
      >>> assert decoder.input_size == encoder.output_size
      >>> assert decoder.output_size == encoder.input_size
docstr: Initializes the `Deferred` module.
  
  Args:
    constructor: A no argument callable which constructs the module to defer
      to. The first time one of the `call_methods` are called the constructor
      will be run and then the constructed module will be called with the same
      method and arguments as the deferred module.
    call_methods: Methods which should trigger construction of the target
      module. The default value configures this module to construct the first
      time `__call__` is run. If you want to add methods other than call you
      should explicitly pass them (optionally), for example
      `call_methods=("__call__", "encode", "decode")`.
    name: Name for the deferred module.
code: def __init__(
      self, constructor, call_methods=("__call__",), name=None
  ):
      """Initializes the `Deferred` module.
  
      Args:
        constructor: A no argument callable which constructs the module to defer
          to. The first time one of the `call_methods` are called the constructor
          will be run and then the constructed module will be called with the same
          method and arguments as the deferred module.
        call_methods: Methods which should trigger construction of the target
          module. The default value configures this module to construct the first
          time `__call__` is run. If you want to add methods other than call you
          should explicitly pass them (optionally), for example
          `call_methods=("__call__", "encode", "decode")`.
        name: Name for the deferred module.
      """
      super().__init__(name=name)
      self._constructor = constructor
      self._target = None
  
      for call_method in call_methods:
          if call_method == "__call__":
              # Has to be handled separately because __call__ cannot be overridden at
              # the instance level.
              # See: https://docs.python.org/3/reference/datamodel.html#special-lookup
              continue
  
          setattr(
              self,
              call_method,
              _materialize_then_call(self, call_method),
          )
  
file_path: sonnet/sonnet/src/deferred.py
imports: from sonnet.src import base
label_desc: Use image node_id 1 to create a new Deferred object from inherited base classes: base with example: obj = Deferred(constructor, call_methods, name)