code: def quadrature_expectation(
      p: ProbabilityDistributionLike,
      obj1: PackedExpectationObject,
      obj2: PackedExpectationObject = None,
      nghp: Optional[int] = None,
  ) -> tf.Tensor:
      """
      Compute the expectation <obj1(x) obj2(x)>_p(x)
      Uses Gauss-Hermite quadrature for approximate integration.
  
      :type p: (mu, cov) tuple or a `ProbabilityDistribution` object
      :type obj1: kernel, mean function, (kernel, inducing_variable), or None
      :type obj2: kernel, mean function, (kernel, inducing_variable), or None
      :param int num_gauss_hermite_points: passed to `_quadrature_expectation` to set
                                           the number of Gauss-Hermite points used
      :return: a 1-D, 2-D, or 3-D tensor containing the expectation
      """
      print(f"2. p={p}, obj1={obj1}, obj2={obj2}")
      p, obj1, feat1, obj2, feat2 = _init_expectation(p, obj1, obj2)
      return dispatch.quadrature_expectation(
          p, obj1, feat1, obj2, feat2, nghp=nghp
      )
  
file_path: GPflow/gpflow/expectations/expectations.py
imports: from typing import Optional, Tuple, Union, cast
  import tensorflow
  from check_shapes import check_shapes
  from ..base import TensorType
  from ..inducing_variables import InducingVariables
  from ..kernels import Kernel
  from ..mean_functions import MeanFunction
  from ..probability_distributions import DiagonalGaussian, Gaussian, MarkovGaussian, ProbabilityDistribution
  from .None import dispatch
label_desc: Use image node_id 2 for calling a global function with example usage: quadrature_expectation(p, obj1, obj2, nghp) and returns: dispatch