class_docstr: DataHandler with **(L)earnable (P)rocessor**
  
  This handler will produce three pieces of data in pd.DataFrame format.
  
  - DK_R / self._data: the raw data loaded from the loader
  - DK_I / self._infer: the data processed for inference
  - DK_L / self._learn: the data processed for learning model.
  
  The motivation of using different processor workflows for learning and inference
  Here are some examples.
  
  - The instrument universe for learning and inference may be different.
  - The processing of some samples may rely on label (for example, some samples hit the limit may need extra processing or be dropped).
  
      - These processors only apply to the learning phase.
  
  Tips for data handler
  
  - To reduce the memory cost
  
      - `drop_raw=True`: this will modify the data inplace on raw data;
  
  - Please note processed data like `self._infer` or `self._learn` are concepts different from `segments` in Qlib's `Dataset` like "train" and "test"
  
      - Processed data like `self._infer` or `self._learn` are underlying data processed with different processors
      - `segments` in Qlib's `Dataset` like "train" and "test" are simply the time segmentations when querying data("train" are often before "test" in time-series).
      - For example, you can query `data._infer` processed by `infer_processors` in the "train" time segmentation.
docstr: fetch data from underlying data source
  
  Parameters
  ----------
  selector : Union[pd.Timestamp, slice, str]
      describe how to select data by index.
  level : Union[str, int]
      which index level to select the data.
  col_set : str
      select a set of meaningful columns.(e.g. features, columns).
  data_key : str
      the data to fetch:  DK_*.
  proc_func: Callable
      please refer to the doc of DataHandler.fetch
  
  Returns
  -------
  pd.DataFrame:
code: def fetch(
      self,
      selector: Union[pd.Timestamp, slice, str] = slice(None, None),
      level: Union[str, int] = "datetime",
      col_set=DataHandler.CS_ALL,
      data_key: DATA_KEY_TYPE = DK_I,
      squeeze: bool = False,
      proc_func: Callable = None,
  ) -> pd.DataFrame:
      """
      fetch data from underlying data source
  
      Parameters
      ----------
      selector : Union[pd.Timestamp, slice, str]
          describe how to select data by index.
      level : Union[str, int]
          which index level to select the data.
      col_set : str
          select a set of meaningful columns.(e.g. features, columns).
      data_key : str
          the data to fetch:  DK_*.
      proc_func: Callable
          please refer to the doc of DataHandler.fetch
  
      Returns
      -------
      pd.DataFrame:
      """
  
      return self._fetch_data(
          data_storage=self._get_df_by_key(data_key),
          selector=selector,
          level=level,
          col_set=col_set,
          squeeze=squeeze,
          proc_func=proc_func,
      )
  
imports: import warnings
  from typing import Callable, Union, Tuple, List, Iterator, Optional
  import pandas
  from qlib.typehint import Literal
  from ...log import get_module_logger, TimeInspector
  from ...utils import init_instance_by_config
  from ...utils.serial import Serializable
  from .utils import fetch_df_by_index, fetch_df_by_col
  from ...utils import lazy_sort_index
  from .loader import DataLoader
  from .None import processor
  from .None import loader
label_desc: Use image node_id 11 for calling the DataHandlerLP obj's underlying member method code with example usage: obj.fetch(selector, level, col_set, data_key, squeeze, proc_func) and returns: self