docs: def do_not_pickle_attributes(*lazy_properties):
      r"""Decorator to assign non-pickable properties.
  
      Used to assign properties which will not be pickled on some class.
      This decorator creates a series of properties whose values won't be
      serialized; instead, their values will be reloaded (e.g. from disk) by
      the :meth:`load` function after deserializing the object.
  
      The decorator can be used to avoid the serialization of bulky
      attributes. Another possible use is for attributes which cannot be
      pickled at all. In this case the user should construct the attribute
      himself in :meth:`load`.
  
      Parameters
      ----------
      \*lazy_properties : strings
          The names of the attributes that are lazy.
  
      Notes
      -----
      The pickling behavior of the dataset is only overridden if the
      dataset does not have a ``__getstate__`` method implemented.
  
      Examples
      --------
      In order to make sure that attributes are not serialized with the
      dataset, and are lazily reloaded after deserialization by the
      :meth:`load` in the wrapped class. Use the decorator with the names of
      the attributes as an argument.
  
      >>> from fuel.datasets import Dataset
      >>> @do_not_pickle_attributes('features', 'targets')
      ... class TestDataset(Dataset):
      ...     def load(self):
      ...         self.features = range(10 ** 6)
      ...         self.targets = range(10 ** 6)[::-1]
  
      """
      def wrap_class(cls):
          if not hasattr(cls, 'load'):
              raise ValueError("no load method implemented")
  
          # Attach the lazy loading properties to the class
          for lazy_property in lazy_properties:
              setattr(cls, lazy_property,
                      property(*lazy_property_factory(lazy_property)))
  
          # Delete the values of lazy properties when serializing
          if not hasattr(cls, '__getstate__'):
              def __getstate__(self):
                  serializable_state = self.__dict__.copy()
                  for lazy_property in lazy_properties:
                      attr = serializable_state.get('_' + lazy_property)
                      # Iterators would lose their state
                      if isinstance(attr, collections.Iterator):
                          raise ValueError("Iterators can't be lazy loaded")
                      serializable_state.pop('_' + lazy_property, None)
                  return serializable_state
              setattr(cls, '__getstate__', __getstate__)
  
          return cls
      return wrap_class