Sliding tiles solver in Python
Whether the code is well designed or not -- is hard to tell without using it. But I have several points:


It's good that you have small functions/methods which do one thing and do well. It's good that you wrote docstrings and comments.
shortest=[i for i,l in enumerate(lengths) if l&lt;=min(lengths)] -- here you are calculating min(lengths) on each loop cycle. Calculate this and put into a variable.
Comply with PEP-8. def cost(path): return len(path) -> have two different lines. np.arange(1,self.size**2) use one space after commas. Game = Sliding_blocks() -- only classes should named CamelCased -> game = SlidingBlocks(). Use pylint to see all warnings.
Use enumerate:

for i in range(len(possible)): 
    actions.append(deepcopy(obj))
    actions[i].move(possible[i])



Will become:

    for i, _possible in enumerate(possible): 
        action = deepcopy(obj)
        actions.append(action)
        action.move(_possible)



Move the imports to the top of the file

def rand_move(self):
    from random import choice

Import module instead of objects from it.

from itertools import product
...
from random import choice



Will become:

import copy
import itertools
import random



Using constants? Name them uppercase and make global. Is it a setting? Pass it as an argument with a default value or store as a class attribute.

def shuffle(self):
    steps = 30
    for i in xrange(steps):
        self.rand_move()

Fail early.

    if list(piece) in self.find_moves():
        self.block[tuple( self.find_free() )] = self.block[tuple(piece)]
        self.block[tuple(piece)] = 0
        return "success"
    else:
        return "error"



This can be rewritten as

        if list(piece) not in self.find_moves():
            return "error"
        ...
        return "success"


This will also reduce indentation.

return "error" -- this is a hardcoded string. Use a constant.


Indeed, using tuples and lists is hard to read and is slow

if list(piece) in self.find_moves():
    self.block[tuple( self.find_free() )] = self.block[tuple(piece)]
    self.block[tuple(piece)] = 0



You should rethink this.