How to reduce responsibility of the main function in strategy pattern (python)
The strategy design pattern is useful mostly when you want to parametrize an algorithm with different behaviours. That implies you would have more than one strategy, which is not the case here. As such, calling this a strategy might be confusing.

Instead, it might be better to view your class as a decorator that can cache the result of a computation in a file. However, that would raise two questions:


Why is the cached data independent from the process that can produce the data, and why is the cached data independent of the input? For example, this behaviour might not be expected:

def multiply_by_2(*xs):
  return [2 * x for x in xs]

def add_3(*xs):
  return [x + 3 for x in xs]

cache.run(multiply_by_2, 1, 2, 3)  #=&gt; [2, 4, 6]
cache.run(multiply_by_2, 3, 4, 5)  #=&gt; [2, 4, 6]
cache.run(add_3,         1, 2, 3)  #=&gt; [2, 4, 6]


That the function may be changed can be prevented by providing the process to the constructor, i.e. associating a cache file with a function before your cache is queried. A different function would then get a different cache.

That the data may vary between invocations is difficult to prevent unless you also store the input data in the file. You may be interested in looking at the functools.lru_cache() decorator that can cache the last n calls in memory, and looks up the correct cache entry by argument values.
If the cache object decorates an existing function (and effectively just offers a single public method run(), then it may be convenient to let the cache also offer a function-like interface: either by implementing a __call__() method, or by actually just using nested functions. With the latter approach, you might implement a decorator like:

def cache(filename, forcecreate=False):
  def inner(process):
    def cached(*input):
      ...  # basically your run() method
    return cached
  return inner


Used like:

@cache("foo.data")
def cache_me(a, b, c):
  ...

result = cache_me(1, 2, 3)


or:

cached_multiply_by_2 = cache("multiply by 2.data")(multiply_by_2)
result = cached_multiply_by_2(1, 2, 3)


It is also possible to do this with an object with a __call__() method. Such an object is actually preferable for debugging since you can inspect the properties of an object.


Other notes:


The self.t field is never read. It can be safely removed.
While __post() reads from self.output, the corresponding __pre() method does not write to that variable, returning a result instead. It would be better if either both methods directly access the self.output state or both methods are "pure" so that __post() would take an parameter.
The names of pre and post are slightly confusing. I would associate them with asserting preconditions and postconditions. Instead, they load() and store() cached data.
Your cache format is unable to cache a None value. When a None is loaded, the process is re-run again. Instead, load/store the data within a container, e.g. a single-element list. Then an empty list indicates the absence of a value, whereas a single-element list (even if that element is None) indicates the presence of a value.
if not self.output is None: would usually be written as if self.output is not None:.
The outer parentheses in if (Path(self.filename).is_file()): are unnecessary.
Output like print("File exists") deep inside your code is not a good idea. If you want to do logging, use a dedicated logging function that is switched off by default. If you output logging, prefer writing to sys.stderr rather than sys.stdout.
any([i is None for i in inputs]) creates a list unnecessarily. A generator expression is sufficient: any(i is None for i in inputs).
It is weird that your class checks the arguments for None-ness. If the wrapped process() cannot handle nones it should check that itself. Or you could define a separate decorator that you could apply independently:

def all_not_none(function):
  @functools.wraps(function)
  def inner(*args):
    if any(x is None for x in args):
      raise ValueError(...)
    return function(*args)
  return inner


(Using the functools.wraps decorator fixes docstrings and names of the returned function object to imitate the original function more closely.)