_LazyTransformDataset

我想了解下父类Dataset的transform方法trans = _LazyTransformDataset(self, fn)这个是什么原理,_LazyTransformDataset不是子类吗,子类初始化不是3个参数(self,data,fn)吗,这里只有2个,查资料不知道怎么查这个原理。

class Dataset(object):
“”"Abstract dataset class. All datasets should have this interface.

Subclasses need to override `__getitem__`, which returns the i-th
element, and `__len__`, which returns the total number elements.

.. note:: An mxnet or numpy array can be directly used as a dataset.
"""
def __getitem__(self, idx):
    raise NotImplementedError

def __len__(self):
    raise NotImplementedError

def filter(self, fn):
    """Returns a new dataset with samples filtered by the
    filter function `fn`.

    Note that if the Dataset is the result of a lazily transformed one with
    transform(lazy=False), the filter is eagerly applied to the transformed
    samples without materializing the transformed result. That is, the
    transformation will be applied again whenever a sample is retrieved after
    filter().

    Parameters
    ----------
    fn : callable
        A filter function that takes a sample as input and
        returns a boolean. Samples that return False are discarded.

    Returns
    -------
    Dataset
        The filtered dataset.
    """
    from . import FilterSampler
    return _SampledDataset(self, FilterSampler(fn, self))

def shard(self, num_shards, index):
    """Returns a new dataset includes only 1/num_shards of this dataset.

    For distributed training, be sure to shard before you randomize the dataset
    (such as shuffle), if you want each worker to reach a unique subset.

    Parameters
    ----------
    num_shards : int
        A integer representing the number of data shards.
    index : int
        A integer representing the index of the current shard.

    Returns
    -------
    Dataset
        The result dataset.
    """
    assert index < num_shards, 'Shard index of out bound: %d out of %d'%(index, num_shards)
    assert num_shards > 0, 'Number of shards must be greater than 0'
    assert index >= 0, 'Index must be non-negative'
    length = len(self)
    shard_len = length // num_shards
    rest = length % num_shards
    # Compute the start index for this partition
    start = shard_len * index + min(index, rest)
    # Compute the end index for this partition
    end = start + shard_len + (index < rest)
    from . import SequentialSampler
    return _SampledDataset(self, SequentialSampler(end - start, start))

def take(self, count):
    """Returns a new dataset with at most `count` number of samples in it.

    Parameters
    ----------
    count : int or None
        A integer representing the number of elements of this dataset that
        should be taken to form the new dataset. If count is None, or if count
        is greater than the size of this dataset, the new dataset will contain
        all elements of this dataset.

    Returns
    -------
    Dataset
        The result dataset.
    """
    if count is None or count > len(self):
        count = len(self)
    from . import SequentialSampler
    return _SampledDataset(self, SequentialSampler(count))

def sample(self, sampler):
    """Returns a new dataset with elements sampled by the sampler.

    Parameters
    ----------
    sampler : Sampler
        A Sampler that returns the indices of sampled elements.

    Returns
    -------
    Dataset
        The result dataset.
    """
    from . import Sampler
    if not isinstance(sampler, Sampler):
        raise TypeError('Invalid sampler type: %s. Expected gluon.data.Sampler instead.'%
                        type(sampler))
    return _SampledDataset(self, sampler)

def transform(self, fn, lazy=True):
    """Returns a new dataset with each sample transformed by the
    transformer function `fn`.

    Parameters
    ----------
    fn : callable
        A transformer function that takes a sample as input and
        returns the transformed sample.
    lazy : bool, default True
        If False, transforms all samples at once. Otherwise,
        transforms each sample on demand. Note that if `fn`
        is stochastic, you must set lazy to True or you will
        get the same result on all epochs.

    Returns
    -------
    Dataset
        The transformed dataset.
    """
    trans = _LazyTransformDataset(self, fn)
    if lazy:
        return trans
    return SimpleDataset([i for i in trans])

def transform_first(self, fn, lazy=True):
    """Returns a new dataset with the first element of each sample
    transformed by the transformer function `fn`.

    This is useful, for example, when you only want to transform data
    while keeping label as is.

    Parameters
    ----------
    fn : callable
        A transformer function that takes the first elemtn of a sample
        as input and returns the transformed element.
    lazy : bool, default True
        If False, transforms all samples at once. Otherwise,
        transforms each sample on demand. Note that if `fn`
        is stochastic, you must set lazy to True or you will
        get the same result on all epochs.

    Returns
    -------
    Dataset
        The transformed dataset.
    """
    return self.transform(_TransformFirstClosure(fn), lazy)

class _LazyTransformDataset(Dataset):
“”“Lazily transformed dataset.”""
def init(self, data, fn):
self._data = data
self._fn = fn

def __len__(self):
    return len(self._data)

def __getitem__(self, idx):
    item = self._data[idx]
    if isinstance(item, tuple):
        return self._fn(*item)
    return self._fn(item)