I assume you mean:

```python
@property
def transform(self):
   """documentation relating to transform"""
   if hasattr(self.steps[-1], 'transform'):
       return self._transform
  else:
       raise AttributeError
```

Sure that'll work, assuming a sensible definition for `_transform`. But seeing as both `_transform` and `transform` would then be templated code repeated for `predict`, `predict_proba`, `predict_log_proba`, `decision_function`, `score`, and potentially other methods not yet invented, why is repeated code better or less vulnerable to bugs? Most of these methods in the current version of `Pipeline` are not separately tested, and no one would notice if they had small aberrations. This way, `_pipeline_property` makes it clear that all these methods are nearly identical; though it should have a comment to that effect.

Of course, you could do similar with something like:

```python
@property
def transform(self):
   """documentation relating to transform"""
   return partial(self._run_pipeline, self.steps[-1].transform)

def _run_pipeline(last_step, X, *args, **kwargs):
    Xt = X
    for name, transform in self.steps[:-1]:
        if transform is not None:
            Xt = transform.transform(Xt)
    return est_fn(Xt, *args, **kwargs)
```

Is that preferred?